Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Comprehensive Explanations of Programs

---

## **Program 1: Longest Nice Subarray**

### **Objective**
The goal of the program is to find the length of the longest "nice" subarray within the input array `nums`. A subarray is considered "nice" if the bitwise AND operation between every pair of elements in the subarray results in `0`. The program efficiently calculates this using a sliding window approach.

---

### **Step-by-Step Explanation**

#### **1. Initialize Variables**
int maxLength = 1, left = 0, usedBits = 0;

#### **2. Iterate Over the Array**
for (int right = 0; right < nums.length; right++) {
while ((usedBits & nums[right]) != 0) {
usedBits ^= nums[left++];
}
usedBits |= nums[right];
maxLength = Math.max(maxLength, right - left + 1);
}
Outer Loop (for): Iterates through each element of the array using the right pointer, which represents the end of the current window.

Inner Loop (while):
(usedBits & nums[right]) != 0: Checks if adding the current element (nums[right]) to the subarray would result in a bitwise AND operation that is non-zero, which violates the "nice" condition.

usedBits ^= nums[left++]: Removes the element at the left pointer from the subarray by performing a bitwise XOR, effectively shrinking the window from the left until the subarray is "nice" again.

Update Subarray:
usedBits |= nums[right]: Adds the current element (nums[right]) to the subarray by updating the usedBits variable using a bitwise OR operation.

maxLength = Math.max(maxLength, right - left + 1): Updates the maximum length of the "nice" subarray encountered so far.

Make DSU of size n by using edges vector.After thet we will have each node parent as if nodes are in same component then parent will be same else parent will be different.

After that we will precompute AND for all nodes and store it in ands vector.
One crucial thing is that we will store AND of component at component's main node(parent) index in ands vector.

Final step: If parent of both query node is same then store AND of that component in ans vector.else store -1.

Complexity
Time complexity: O(E+Q)
E : Size of edges vector
Q : Size of query vector

Space complexity:O(N)
N : No. of nodes
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import java.util.*;

class Solution {
class DSU {
int[] par, rank;

public DSU(int n) {
par = new int[n + 1];
rank = new int[n + 1];
Arrays.fill(rank, 1);
for (int i = 0; i <= n; i++) par[i] = i;
}

public int find_set(int v) {
if (v == par[v]) return v;
return par[v] = find_set(par[v]); // Path compression
}

public void union_sets(int a, int b) {
a = find_set(a);
b = find_set(b);
if (a != b) {
if (rank[a] < rank[b]) {
int temp = a;
a = b;
b = temp;
}
par[b] = a;
rank[a] += rank[b];
}
}
}

public List<Integer> minimumCost(int n, int[][] edges, int[][] query) {
DSU ds = new DSU(n);
int[] ands = new int[n + 1];
Arrays.fill(ands, -1);

for (int[] it : edges) {
ds.union_sets(it[0], it[1]);
}

for (int[] it : edges) {
int root = ds.find_set(it[0]);
int cur = ands[root];
ands[root] = (cur == -1) ? it[2] : (cur & it[2]);
}

List<Integer> ans = new ArrayList<>();
for (int[] it : query) {
if (ds.find_set(it[0]) == ds.find_set(it[1])) {
ans.add(ands[ds.find_set(it[0])]);
} else {
ans.add(-1);
}
}
return ans;
}
}