├── 160 ├── a.out ├── day10.cpp ├── day16.cpp ├── day9.cpp ├── day21.cpp ├── day26.cpp ├── day11.cpp ├── day22.cpp ├── day13.cpp ├── day12.cpp ├── day17.cpp ├── day24.cpp ├── day25.cpp ├── day19.cpp ├── day20.cpp ├── day18.cpp ├── day14.cpp └── day15.cpp ├── .gitignore ├── UniqueNumberI.cpp ├── MayPOTD ├── SumOfSubstringsOfNumber.cpp ├── BitonicElement.cpp ├── nthRowPascalTriangle.cpp ├── nCr.cpp ├── DiceSum.cpp ├── KthLargestSumContiguousSubarray.cpp ├── KthSmallestInMultiplicationTable.cpp ├── ClosestNeighborBST.cpp ├── PythagoreanTriplet.cpp ├── MinimumDeletions.cpp ├── kthElementInMatrix.cpp ├── MissingElementOfAP.cpp ├── LookAndSayPattern.cpp ├── LeafNodesFromPreorder.cpp ├── LongestSubarrayWithMajorityGreaterThanK.cpp ├── SearchAlmostSortedArray.cpp ├── SubstringWithSameFirstAndLast.cpp ├── RectangleWithCorner1.cpp ├── SumOfNodesOnLongestPath.cpp ├── RootToLeafPaths.cpp ├── LargestNumberInKSwaps.cpp ├── LeftViewBinaryTree.cpp ├── InsertInSortedCircularLinkedList.cpp ├── SmallestDistinctWindow.cpp ├── PrimeList.cpp ├── LevelOrderSpiral.cpp ├── PredecessorAndSuccessor.cpp ├── SmallestRangeInKLists.cpp ├── SortAfterTransformation.cpp ├── MeetingRoomsIII.cpp └── BurningTree.cpp ├── UniqueNumberIII.cpp ├── MissingElement.cpp ├── OnlyRepetitiveElement.cpp ├── FloydWarshall.cpp ├── ReverseArray.cpp ├── StockBuyAndSellLimit.cpp ├── StockBuyAndSellNoLimit.cpp ├── JunePOTD ├── UniquePathsInGrid.cpp ├── CountPairSum.cpp ├── LCSThreeStrings.cpp └── SubstringWithKDistinct.cpp ├── OctoberPOTD ├── TopKFrequentElements.cpp └── KClosestToOrigin.cpp ├── CloneUndirectedGraph.cpp ├── MajorityElementI.cpp ├── LoopLengthLL.cpp ├── SortLL.cpp ├── MaxSumOfNonAdjacentNodes.cpp ├── BellmanFord.cpp ├── BridgeEdge.cpp ├── IsHeap.cpp ├── RotateArray.cpp ├── UniqueNumberII.cpp ├── MoveAllZeroesToEnd.cpp ├── TopologicalSort.cpp ├── DirectedGraphCycle.cpp ├── FloodFillAlgorithm.cpp ├── CountIslands.cpp ├── TrieImplementation.cpp ├── MajorityElementII.cpp ├── StringMultiplication.cpp ├── UndirectedGraphCycle.cpp ├── MaxXOR.cpp ├── DijsktraAlgorithm.cpp ├── NextGreaterPermutation.cpp ├── ArticulationPoints.cpp ├── MinWeightCycle.cpp ├── ConnectHouses.cpp ├── AlienDictionary.cpp └── RottenOranges.cpp /160/a.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmd-anurag/gfg/main/160/a.out -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore files with no extension 2 | * 3 | !*.* 4 | !*/ 5 | /.vscode -------------------------------------------------------------------------------- /UniqueNumberI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution 5 | { 6 | public: 7 | int findUnique(vector &arr) 8 | { 9 | // code here 10 | int res = 0; 11 | for (int i : arr) 12 | { 13 | res ^= i; 14 | } 15 | return res; 16 | } 17 | }; -------------------------------------------------------------------------------- /MayPOTD/SumOfSubstringsOfNumber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::string; 3 | 4 | class Solution { 5 | public: 6 | int sumSubstrings(string &s) { 7 | int n = s.size(); 8 | int64_t sum = 0, f = 0; 9 | for (int i = 0; i < n; i++) { 10 | f = f * 10 + (s[i] - '0') * (i + 1); 11 | sum += f; 12 | } 13 | return (int)sum; 14 | } 15 | }; -------------------------------------------------------------------------------- /UniqueNumberIII.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution 5 | { 6 | public: 7 | int getSingle(vector &arr) 8 | { 9 | // code here 10 | int ones = 0; 11 | int twos = 0; 12 | 13 | for (int x : arr) 14 | { 15 | ones = (ones ^ x) & ~twos; 16 | twos = (twos ^ x) & ~ones; 17 | } 18 | return ones; 19 | } 20 | }; -------------------------------------------------------------------------------- /MayPOTD/BitonicElement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::vector, std::max; 4 | 5 | class Solution { 6 | public: 7 | int findMaximum(vector &arr) { 8 | // code here 9 | // wait what 10 | int bitonicPoint = INT_MIN; 11 | for(int x : arr) { 12 | bitonicPoint = max(x, bitonicPoint); 13 | } 14 | return bitonicPoint; 15 | } 16 | }; -------------------------------------------------------------------------------- /160/day10.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class Solution { 5 | public: 6 | int maxSubarraySum(std::vector &arr) { 7 | // Code here 8 | int result = INT_MIN; 9 | int sum = 0; 10 | 11 | for(int x : arr) 12 | { 13 | sum += x; 14 | result = std::max(sum, result); 15 | if(sum < 0) sum = 0; 16 | 17 | } 18 | return result; 19 | } 20 | }; -------------------------------------------------------------------------------- /MissingElement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution 5 | { 6 | public: 7 | int missingNum(vector &arr) 8 | { 9 | // code here 10 | int e = 0; 11 | int a = 0; 12 | 13 | for (int i : arr) 14 | { 15 | a ^= i; 16 | } 17 | int n = arr.size(); 18 | for (int i = 1; i <= n + 1; ++i) 19 | { 20 | e ^= i; 21 | } 22 | return a ^ e; 23 | } 24 | }; -------------------------------------------------------------------------------- /OnlyRepetitiveElement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution 5 | { 6 | public: 7 | int findDuplicate(vector &arr) 8 | { 9 | int n = arr.size(); 10 | 11 | int actualXOR = 0; 12 | for (int x : arr) 13 | { 14 | actualXOR ^= x; 15 | } 16 | int expectedXOR = 0; 17 | for (int i = 1; i <= n - 1; ++i) 18 | { 19 | expectedXOR ^= i; 20 | } 21 | return expectedXOR ^ actualXOR; 22 | } 23 | }; -------------------------------------------------------------------------------- /160/day16.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::string; 3 | class Solution { 4 | public: 5 | bool areAnagrams(string& s1, string& s2) { 6 | // code here 7 | int arr[26] = {0}; 8 | 9 | for(char c : s1) 10 | { 11 | arr[c - 'a']--; 12 | } 13 | for(char c : s2) 14 | { 15 | arr[c - 'a']++; 16 | } 17 | 18 | for(int i = 0; i < 26; ++i) { 19 | if(arr[i]) return false; 20 | } 21 | return true; 22 | } 23 | }; -------------------------------------------------------------------------------- /MayPOTD/nthRowPascalTriangle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector; 5 | 6 | class Solution 7 | { 8 | public: 9 | vector nthRowOfPascalTriangle(int n) 10 | { 11 | // code here 12 | vector result(n); 13 | result[0] = 1; 14 | 15 | for (int i = 1; i < n; ++i) 16 | { 17 | result[i] = result[i - 1] * (n - i) / i; 18 | } 19 | 20 | return result; 21 | } 22 | }; 23 | 24 | int main() 25 | { 26 | Solution s; 27 | s.nthRowOfPascalTriangle(4); 28 | } -------------------------------------------------------------------------------- /MayPOTD/nCr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::min; 3 | using std::vector; 4 | 5 | class Solution { 6 | public: 7 | int nCr(int n, int r) 8 | { 9 | // code here 10 | vector> dp(n+1, vector(r+1, 0)); 11 | 12 | for(int i = 0; i <= n; ++i) { 13 | for(int j = 0; j <= min(i, r); ++j) { 14 | if(j == 0 || j == i) dp[i][j] = 1; 15 | else 16 | dp[i][j] = dp[i-1][j-1] + dp[i-1][j]; 17 | } 18 | } 19 | 20 | return dp[n][r]; 21 | } 22 | }; -------------------------------------------------------------------------------- /MayPOTD/DiceSum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution { 5 | public: 6 | int noOfWays(int m, int n, int x) { 7 | // code here 8 | vector> dp(n+1, vector(x+1, 0)); 9 | dp[0][0] = 1; 10 | 11 | for (int i = 1; i <= n; ++i) { 12 | for (int j = 1; j <= x; ++j) { 13 | for (int f = 1; f <= m; ++f) { 14 | if (j >= f) 15 | dp[i][j] += dp[i-1][j-f]; 16 | } 17 | } 18 | } 19 | 20 | return dp[n][x]; 21 | } 22 | }; -------------------------------------------------------------------------------- /FloydWarshall.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution { 5 | public: 6 | const int INF = 1e8; 7 | 8 | void floydWarshall(vector> &dist) { 9 | // Code here 10 | int n = dist.size(); 11 | 12 | for(int k = 0; k < n; ++k) 13 | for(int i = 0; i < n; ++i) 14 | for(int j = 0; j < n; ++j) { 15 | if(dist[i][k] < INF && dist[k][j] < INF) 16 | { 17 | dist[i][j] = min(dist[i][k] + dist[k][j], dist[i][j]); 18 | } 19 | } 20 | } 21 | }; -------------------------------------------------------------------------------- /ReverseArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Solution { 6 | // pretty easy 7 | public: 8 | void reverseArray(vector &arr) { 9 | // code here 10 | int left = 0; 11 | int right = arr.size()-1; 12 | 13 | while(left < right) 14 | { 15 | swap(arr[left++], arr[right--]); 16 | } 17 | } 18 | 19 | // Time Complexity - O(n); 20 | // Space Complexity - O(1); 21 | 22 | private: 23 | void swap(int &x, int &y) { 24 | int t = x; 25 | x = y; 26 | y = t; 27 | } 28 | 29 | 30 | }; -------------------------------------------------------------------------------- /MayPOTD/KthLargestSumContiguousSubarray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Solution 6 | { 7 | public: 8 | int kthLargest(vector &arr, int k) 9 | { 10 | priority_queue, greater> pq; 11 | int n = arr.size(); 12 | for (int i = 0; i < n; ++i) 13 | { 14 | long long sum = 0; 15 | for (int j = i; j < n; ++j) 16 | { 17 | sum += arr[j]; 18 | pq.push(sum); 19 | if (pq.size() > k) 20 | pq.pop(); 21 | } 22 | } 23 | return pq.top(); 24 | } 25 | }; -------------------------------------------------------------------------------- /MayPOTD/KthSmallestInMultiplicationTable.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | class Solution { 5 | public: 6 | int kthSmallest(int m, int n, int k) { 7 | // code here 8 | int low = 1; 9 | int high = m*n; 10 | 11 | while(low < high) { 12 | int mid = low + (high - low)/2; 13 | int count = 0; 14 | 15 | for(int i = 1; i <= m; ++i) { 16 | count += std::min(n, mid / i); 17 | } 18 | 19 | if(count < k) { 20 | low = mid + 1; 21 | } 22 | else { 23 | high = mid; 24 | } 25 | } 26 | 27 | return low; 28 | } 29 | }; -------------------------------------------------------------------------------- /160/day9.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class Solution { 5 | public: 6 | int getMinDiff(std::vector &arr, int k) { 7 | 8 | int n = arr.size(); 9 | 10 | std::sort(arr.begin(), arr.end()); 11 | 12 | int answer = arr[n-1] - arr[0]; 13 | 14 | for(int i = 0; i < n; ++i) 15 | { 16 | if(arr[i] - k < 0) continue; 17 | 18 | int minHeight = std::min(arr[0] + k, arr[i] - k); 19 | int maxHeight = std::max(arr[i-1] + k, arr[n-1] - k); 20 | 21 | answer =std::min(answer, maxHeight - minHeight); 22 | } 23 | 24 | return answer; 25 | } 26 | }; -------------------------------------------------------------------------------- /StockBuyAndSellLimit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution { 5 | public: 6 | int maximumProfit(vector &prices) { 7 | // code here 8 | 9 | 10 | int profit = 0; 11 | int maxProfit = 0; 12 | 13 | int minCP = prices[0]; 14 | 15 | // simply track the minimum CP seen so far and calculate profit if sold on that day for each day 16 | for(int i : prices) { 17 | minCP = min(minCP, i); 18 | profit = i - minCP; 19 | maxProfit = max(maxProfit, profit); 20 | } 21 | 22 | return maxProfit; 23 | 24 | } 25 | }; -------------------------------------------------------------------------------- /StockBuyAndSellNoLimit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | int maximumProfit(vector &prices) { 8 | // code here 9 | 10 | // just greedily sum all upward slopes 11 | // since it is always profitable to buy low and sell high 12 | // multiple profitable small trades (prices[i] < prices[i+1]) equals the optimal larger trade 13 | 14 | int n = prices.size(); 15 | int profit = 0; 16 | for(int i = 0; i < n-1; ++i) { 17 | if(prices[i] < prices[i+1]) { 18 | profit += prices[i+1] - prices[i]; 19 | } 20 | } 21 | return profit; 22 | } 23 | }; -------------------------------------------------------------------------------- /160/day21.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | using std::swap; 4 | 5 | class Solution { 6 | public: 7 | void sort012(vector& arr) { 8 | // code here 9 | int low = 0; 10 | int mid = 0; 11 | int high = arr.size() - 1; 12 | 13 | while(mid <= high) 14 | { 15 | if(arr[mid] == 0) 16 | { 17 | swap(arr[mid], arr[low]); 18 | ++mid; 19 | ++low; 20 | } 21 | else if(arr[mid] == 1) 22 | { 23 | ++mid; 24 | } 25 | else { 26 | swap(arr[mid], arr[high]); 27 | --high; 28 | } 29 | } 30 | } 31 | }; -------------------------------------------------------------------------------- /MayPOTD/ClosestNeighborBST.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Node 3 | { 4 | public: 5 | int data; 6 | Node *left; 7 | Node *right; 8 | 9 | Node(int x) 10 | { 11 | data = x; 12 | left = nullptr; 13 | right = nullptr; 14 | } 15 | }; 16 | 17 | class Solution 18 | { 19 | public: 20 | int findMaxFork(Node *root, int k) 21 | { 22 | int ans = -1; 23 | Node *cur = root; 24 | while (cur) 25 | { 26 | if (cur->data <= k) 27 | { 28 | ans = cur->data; 29 | cur = cur->right; 30 | } 31 | else 32 | { 33 | cur = cur->left; 34 | } 35 | } 36 | return ans; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /MayPOTD/PythagoreanTriplet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::vector; 4 | 5 | class Solution { 6 | public: 7 | bool pythagoreanTriplet(vector& arr) { 8 | // code here 9 | std::unordered_set sq; 10 | 11 | for(int num : arr) { 12 | sq.insert(num * num); 13 | } 14 | 15 | for(int i = 0; i < arr.size(); ++i) { 16 | for(int j = i+1; j < arr.size(); ++j) { 17 | int sum = arr[i]*arr[i] + arr[j]*arr[j]; 18 | if(sq.count(sum)) { 19 | return true; 20 | } 21 | } 22 | } 23 | return false; 24 | } 25 | // lol this got accepted? i for sure was prepared for a TLE 26 | }; -------------------------------------------------------------------------------- /MayPOTD/MinimumDeletions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using std::string; 6 | 7 | class Solution { 8 | public: 9 | int minDeletions(string s) { 10 | // code here 11 | int n = s.size(); 12 | 13 | string t = s; 14 | std::reverse(t.begin(), t.end()); 15 | std::vector> dp(n+1, std::vector(n+1)); 16 | 17 | for(int i = 1; i <= n; ++i) { 18 | 19 | for(int j = 1; j <= n; ++j) { 20 | if (s[i-1] == t[j-1]) 21 | dp[i][j] = dp[i-1][j-1] + 1; 22 | else 23 | dp[i][j] = std::max(dp[i-1][j], dp[i][j-1]); 24 | } 25 | 26 | } 27 | 28 | return n - dp[n][n]; 29 | } 30 | }; -------------------------------------------------------------------------------- /MayPOTD/kthElementInMatrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::vector; 4 | 5 | class Solution { 6 | public: 7 | int kthSmallest(vector> &matrix, int k) { 8 | int n = matrix.size(); 9 | int low = matrix[0][0]; 10 | int high = matrix[n - 1][n - 1]; 11 | while (low < high) { 12 | int mid = low + (high - low) / 2; 13 | int count = 0; 14 | for (int i = 0; i < n; ++i) { 15 | count += upper_bound(matrix[i].begin(), matrix[i].end(), mid) - matrix[i].begin(); 16 | } 17 | if (count < k) { 18 | low = mid + 1; 19 | } else { 20 | high = mid; 21 | } 22 | } 23 | return low; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /MayPOTD/MissingElementOfAP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution { 5 | public: 6 | int findMissing(vector &arr) { 7 | 8 | int n = arr.size() + 1; 9 | int a = arr[0]; 10 | int d = std::min(arr[1] - arr[0], arr.back() - arr[arr.size() - 2]); 11 | 12 | int left = 0; 13 | int right = arr.size() - 1; 14 | 15 | while(left <= right) { 16 | int mid = left + (right - left) / 2; 17 | int expected = a + mid * d; 18 | 19 | if(arr[mid] == expected) { 20 | left = mid + 1; 21 | } 22 | else { 23 | right = mid - 1; 24 | } 25 | } 26 | 27 | return a + left * d; 28 | } 29 | }; -------------------------------------------------------------------------------- /MayPOTD/LookAndSayPattern.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::string; 3 | 4 | class Solution 5 | { 6 | public: 7 | string helper(string t) 8 | { 9 | int n = t.length(); 10 | 11 | string output = ""; 12 | 13 | for (int i = 0; i < n; i++) 14 | { 15 | char letter = t[i]; 16 | int freq = 0; 17 | 18 | int j = i; 19 | for (; j < n && t[j] == letter; ++j) 20 | { 21 | ++freq; 22 | } 23 | i = j - 1; 24 | 25 | output += std::to_string(freq) + letter; 26 | } 27 | 28 | return output; 29 | } 30 | 31 | string countAndSay(int n) 32 | { 33 | if (n == 1) 34 | return "1"; 35 | 36 | return helper(countAndSay(n - 1)); 37 | } 38 | }; -------------------------------------------------------------------------------- /160/day26.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::vector, std::sort; 5 | 6 | bool compare(const vector &a, const vector &b) { 7 | return a[1] < b[1]; 8 | } 9 | class Solution { 10 | public: 11 | int minRemoval(vector> &intervals) { 12 | // code here 13 | sort(intervals.begin(), intervals.end(), compare); 14 | 15 | int lastValid = intervals[0][1]; 16 | int count = 0; 17 | 18 | for(int i = 1; i < intervals.size(); ++i) { 19 | if(intervals[i][0] < lastValid) { 20 | ++count; 21 | } 22 | else { 23 | lastValid = intervals[i][1]; 24 | } 25 | // cout << pair[1] << " "; 26 | } 27 | 28 | return count; 29 | } 30 | private: 31 | }; 32 | -------------------------------------------------------------------------------- /MayPOTD/LeafNodesFromPreorder.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::vector; 4 | 5 | class Solution { 6 | public: 7 | vector leafNodes(vector& preorder) { 8 | vector result; 9 | int idx = 0; 10 | dfs(LLONG_MIN, LLONG_MAX, preorder, idx, result); 11 | return result; 12 | } 13 | 14 | private: 15 | 16 | bool dfs(long low, long high, 17 | const vector& pre, int& idx, 18 | vector& result) 19 | { 20 | if (idx >= pre.size() || pre[idx] < low || pre[idx] > high) 21 | return false; 22 | 23 | int val = pre[idx++]; 24 | bool hasL = dfs(low, val, pre, idx, result); 25 | bool hasR = dfs(val, high, pre, idx, result); 26 | if (!hasL && !hasR) 27 | result.push_back(val); 28 | return true; 29 | } 30 | }; -------------------------------------------------------------------------------- /JunePOTD/UniquePathsInGrid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution { 5 | public: 6 | int uniquePaths(vector> &grid) { 7 | int n = grid.size(); 8 | int m = grid[0].size(); 9 | vector> dp(n, vector(m, 0)); 10 | 11 | if (grid[0][0] == 1) 12 | return 0; 13 | 14 | dp[0][0] = 1; 15 | 16 | for (int i = 0; i < n; ++i) { 17 | for (int j = 0; j < m; ++j) { 18 | if (grid[i][j] == 1) { 19 | dp[i][j] = 0; 20 | } else { 21 | if (i > 0) 22 | dp[i][j] += dp[i - 1][j]; 23 | if (j > 0) 24 | dp[i][j] += dp[i][j - 1]; 25 | } 26 | } 27 | } 28 | 29 | return dp[n - 1][m - 1]; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /160/day11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | class Solution { 4 | public: 5 | int maxProduct(std::vector &arr) { 6 | int startToEndProduct = 1; 7 | int endToStartProduct = 1; 8 | int answer = INT_MIN; 9 | 10 | int n = arr.size(); 11 | 12 | for(int i = 0; i < n; ++i) 13 | { 14 | startToEndProduct *= arr[i]; 15 | endToStartProduct *= arr[n-i-1]; 16 | answer = std::max(answer, startToEndProduct); 17 | answer = std::max(answer, endToStartProduct); 18 | 19 | if(arr[i] == 0) 20 | { 21 | startToEndProduct = 1; 22 | } 23 | if(arr[n-i-1] == 0) 24 | { 25 | endToStartProduct = 1; 26 | } 27 | } 28 | 29 | return answer; 30 | } 31 | }; -------------------------------------------------------------------------------- /MayPOTD/LongestSubarrayWithMajorityGreaterThanK.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | using std::max; 4 | using std::vector; 5 | 6 | // User function Template for C++ 7 | class Solution 8 | { 9 | public: 10 | int longestSubarray(vector &arr, int k) 11 | { 12 | int n = arr.size(); 13 | vector pref(n + 1); 14 | for (int i = 0; i < n; i++) 15 | pref[i + 1] = pref[i] + (arr[i] > k ? 1 : -1); 16 | vector st; 17 | for (int i = 0; i <= n; i++) 18 | if (st.empty() || pref[i] < pref[st.back()]) 19 | st.push_back(i); 20 | int ans = 0; 21 | for (int j = n; j >= 0; j--) 22 | while (!st.empty() && pref[j] > pref[st.back()]) 23 | { 24 | ans = max(ans, j - st.back()); 25 | st.pop_back(); 26 | } 27 | return ans; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /MayPOTD/SearchAlmostSortedArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution { 5 | public: 6 | int findTarget(vector& arr, int target) { 7 | // code here 8 | int left = 0; 9 | int right = arr.size() - 1; 10 | 11 | while(left <= right) { 12 | int mid = left + (right - left) / 2; 13 | if(arr[mid] == target) { 14 | return mid; 15 | } 16 | else if(mid - 1 >= 0 && arr[mid-1] == target) 17 | return mid-1; 18 | else if(mid + 1 < arr.size() && arr[mid+1] == target) 19 | return mid+1; 20 | else if(target > arr[mid]) { 21 | left = mid + 1; 22 | } 23 | else { 24 | right = mid - 1; 25 | } 26 | } 27 | 28 | return -1; 29 | } 30 | }; -------------------------------------------------------------------------------- /OctoberPOTD/TopKFrequentElements.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using std::unordered_map, std::priority_queue, std::vector, std::pair; 5 | 6 | class Solution { 7 | public: 8 | vector topKFreq(vector &arr, int k) { 9 | // Code here 10 | unordered_map hashmap; 11 | 12 | for(int i : arr) { 13 | hashmap[i]++; 14 | } 15 | priority_queue> maxh; 16 | 17 | for(const auto& pair: hashmap) { 18 | maxh.push({pair.second, pair.first}); 19 | } 20 | vector result; 21 | 22 | int count = 0; 23 | while(!maxh.empty() && count 2 | using std::vector; 3 | 4 | class Solution { 5 | public: 6 | int countPairs(vector> &mat1, vector> &mat2, int x) { 7 | int n = mat1.size(); 8 | vector flat1, flat2; 9 | for (int i = 0; i < n; ++i) { 10 | flat1.insert(flat1.end(), mat1[i].begin(), mat1[i].end()); 11 | flat2.insert(flat2.end(), mat2[i].begin(), mat2[i].end()); 12 | } 13 | int count = 0; 14 | int i = 0, j = flat2.size() - 1; 15 | while (i < flat1.size() && j >= 0) { 16 | int sum = flat1[i] + flat2[j]; 17 | if (sum == x) { 18 | ++count; 19 | ++i; 20 | --j; 21 | } else if (sum < x) { 22 | ++i; 23 | } else { 24 | --j; 25 | } 26 | } 27 | return count; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /JunePOTD/LCSThreeStrings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using std::vector, std::string; 5 | 6 | class Solution { 7 | public: 8 | int lcsOf3(string& s1, string& s2, string& s3) { 9 | int n1 = s1.length(), n2 = s2.length(), n3 = s3.length(); 10 | vector>> dp(n1 + 1, vector>(n2 + 1, vector(n3 + 1, 0))); 11 | 12 | for (int i = 1; i <= n1; ++i) { 13 | for (int j = 1; j <= n2; ++j) { 14 | for (int k = 1; k <= n3; ++k) { 15 | if (s1[i-1] == s2[j-1] && s1[i-1] == s3[k-1]) { 16 | dp[i][j][k] = 1 + dp[i-1][j-1][k-1]; 17 | } else { 18 | dp[i][j][k] = std::max({dp[i-1][j][k], dp[i][j-1][k], dp[i][j][k-1]}); 19 | } 20 | } 21 | } 22 | } 23 | 24 | return dp[n1][n2][n3]; 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /160/day22.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | class Solution { 8 | public: 9 | int hIndex(vector& citations) { 10 | // code here 11 | int n = citations.size(); 12 | 13 | vector freq(n+1, 0); 14 | 15 | int index = n; 16 | 17 | for(int i = 0; i < n; ++i) { 18 | if(citations[i] >= n) { 19 | 20 | freq[n]++; 21 | } 22 | else { 23 | 24 | freq[citations[i]]++; 25 | } 26 | } 27 | 28 | int sum = freq[n]; 29 | 30 | while(sum < index) 31 | { 32 | --index; 33 | sum += freq[index]; 34 | 35 | } 36 | return index; 37 | } 38 | }; 39 | 40 | int main() 41 | { 42 | Solution s; 43 | vector citations = {6, 0, 3, 5, 3}; 44 | cout << s.hIndex(citations) << '\n'; 45 | } -------------------------------------------------------------------------------- /JunePOTD/SubstringWithKDistinct.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | using std::unordered_map; 5 | using std::string; 6 | 7 | class Solution { 8 | public: 9 | int countAtMostK(string& s, int k) { 10 | int n = s.length(); 11 | unordered_map freq; 12 | int left = 0, right = 0; 13 | int count = 0; 14 | 15 | for (right = 0; right < n; ++right) { 16 | freq[s[right]]++; 17 | 18 | while (freq.size() > k) { 19 | freq[s[left]]--; 20 | if (freq[s[left]] == 0) { 21 | freq.erase(s[left]); 22 | } 23 | left++; 24 | } 25 | 26 | count += (right - left + 1); 27 | } 28 | return count; 29 | } 30 | 31 | int countSubstr(string& s, int k) { 32 | if (k == 0) return 0; 33 | return countAtMostK(s, k) - countAtMostK(s, k - 1); 34 | } 35 | }; -------------------------------------------------------------------------------- /MayPOTD/SubstringWithSameFirstAndLast.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::string, std::vector; 4 | 5 | class Solution { 6 | public: 7 | int countSubstring(string &s) { 8 | // code here 9 | 10 | // int result = n; 11 | 12 | // for(int i = 0; i < n; ++i) { 13 | // for(int j = i+1; j < n; ++j) { 14 | // if(s.at(i) == s.at(j)) ++result; 15 | // } 16 | // } 17 | // return result; 18 | 19 | // TLE :( 20 | 21 | vector map(26, 0); 22 | for(char c : s) { 23 | map[c - 'a']++; 24 | } 25 | 26 | int result = 0; 27 | 28 | // if a character c appears at k indices, the number of valid substrings possible (start and last both = c) is kC2 + k 29 | 30 | for(int i = 0; i < 26; ++i) { 31 | int k = map[i]; 32 | result += (k * (k-1)) / 2 + k; 33 | } 34 | 35 | return result; 36 | } 37 | }; -------------------------------------------------------------------------------- /MayPOTD/RectangleWithCorner1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::unordered_set, std::vector; 5 | 6 | class Solution 7 | { 8 | public: 9 | bool ValidCorner(vector> &mat) 10 | { 11 | int n = mat.size(), m = mat[0].size(); 12 | unordered_set seen; 13 | for (int i = 0; i < n; ++i) 14 | { 15 | vector cols; 16 | for (int j = 0; j < m; ++j) 17 | if (mat[i][j] == 1) 18 | cols.push_back(j); 19 | for (int a = 0; a < cols.size(); ++a) 20 | { 21 | for (int b = a + 1; b < cols.size(); ++b) 22 | { 23 | long long key = (long long)cols[a] * m + cols[b]; 24 | if (seen.count(key)) 25 | return true; 26 | seen.insert(key); 27 | } 28 | } 29 | } 30 | return false; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /MayPOTD/SumOfNodesOnLongestPath.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Node { 3 | public: 4 | int data; 5 | Node *left; 6 | Node *right; 7 | 8 | Node(int x) { 9 | data = x; 10 | left = nullptr; 11 | right = nullptr; 12 | } 13 | }; 14 | 15 | class Solution { 16 | public: 17 | int sumOfLongRootToLeafPath(Node *root) { 18 | int maxLen = 0, maxSum = 0; 19 | dfs(root, 0, 0, maxLen, maxSum); 20 | return maxSum; 21 | } 22 | private: 23 | void dfs(Node *node, int len, int sum, int &maxLen, int &maxSum) { 24 | if (!node) return; 25 | len++; 26 | sum += node->data; 27 | if (!node->left && !node->right) { 28 | if (len > maxLen || (len == maxLen && sum > maxSum)) { 29 | maxLen = len; 30 | maxSum = sum; 31 | } 32 | return; 33 | } 34 | dfs(node->left, len, sum, maxLen, maxSum); 35 | dfs(node->right, len, sum, maxLen, maxSum); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /MayPOTD/RootToLeafPaths.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | struct Node 5 | { 6 | int data; 7 | struct Node *left; 8 | struct Node *right; 9 | 10 | Node(int x) 11 | { 12 | data = x; 13 | left = right = nullptr; 14 | } 15 | }; 16 | 17 | class Solution 18 | { 19 | public: 20 | vector> Paths(Node *root) 21 | { 22 | // code here 23 | vector> result; 24 | vector path; 25 | solve(root, result, path); 26 | 27 | return result; 28 | } 29 | 30 | private: 31 | void solve(Node *root, vector> &result, vector path) 32 | { 33 | if (!root) 34 | { 35 | return; 36 | } 37 | 38 | path.push_back(root->data); 39 | 40 | if (!root->left && !root->right) 41 | { 42 | result.push_back(path); 43 | } 44 | 45 | solve(root->left, result, path); 46 | solve(root->right, result, path); 47 | } 48 | }; -------------------------------------------------------------------------------- /CloneUndirectedGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct Node { 6 | int val; 7 | vector neighbors; 8 | Node() { 9 | val = 0; 10 | neighbors = vector(); 11 | } 12 | Node(int _val) { 13 | val = _val; 14 | neighbors = vector(); 15 | } 16 | Node(int _val, vector _neighbors) { 17 | val = _val; 18 | neighbors = _neighbors; 19 | } 20 | }; 21 | 22 | class Solution { 23 | public: 24 | unordered_map cloned; 25 | 26 | Node* cloneGraph(Node* node) { 27 | if (!node) return nullptr; 28 | if (cloned.find(node) != cloned.end()) return cloned[node]; 29 | 30 | Node* clone = new Node(node->val); 31 | cloned[node] = clone; 32 | 33 | for (auto neighbor : node->neighbors) { 34 | clone->neighbors.push_back(cloneGraph(neighbor)); 35 | } 36 | 37 | return clone; 38 | } 39 | }; -------------------------------------------------------------------------------- /160/day13.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Solution { 4 | public: 5 | int missingNumber(std::vector &arr) { 6 | // code here 7 | int n = arr.size(); 8 | 9 | int i = 0; 10 | while(i < n) 11 | { 12 | if(arr[i] < 1 || arr[i] > n) // out of range 13 | { 14 | ++i; 15 | continue; 16 | } 17 | 18 | int correctIndex = arr[i] - 1; 19 | 20 | if(arr[i] == arr[correctIndex]) // already at correct index 21 | { 22 | ++i; 23 | continue; 24 | } 25 | 26 | 27 | swap(arr[i], arr[correctIndex]); 28 | } 29 | 30 | for(int i = 0; i < n; ++i) 31 | { 32 | if(arr[i] != i+1) return i+1; 33 | } 34 | } 35 | private: 36 | void swap(int &a, int &b) 37 | { 38 | int temp = a; 39 | a = b; 40 | b = temp; 41 | } 42 | }; -------------------------------------------------------------------------------- /MajorityElementI.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution 5 | { 6 | public: 7 | int majorityElement(vector &arr) 8 | { 9 | if (arr.empty()) 10 | return -1; 11 | 12 | // code here 13 | int candidate = arr[0]; 14 | int count = 0; 15 | 16 | for (int x : arr) 17 | { 18 | if (count == 0) 19 | { 20 | candidate = x; 21 | } 22 | 23 | if (x == candidate) 24 | ++count; 25 | else 26 | { 27 | --count; 28 | } 29 | } 30 | 31 | count = 0; 32 | for (int x : arr) 33 | { 34 | if (x == candidate) 35 | { 36 | ++count; 37 | } 38 | } 39 | 40 | int n = arr.size(); 41 | if (count * 2 > n) 42 | { 43 | return candidate; 44 | } 45 | else 46 | { 47 | return -1; 48 | } 49 | } 50 | }; -------------------------------------------------------------------------------- /OctoberPOTD/KClosestToOrigin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::priority_queue, std::vector, std::pair, std::greater; 4 | 5 | class Solution { 6 | public: 7 | vector> kClosest(vector>& points, int k) { 8 | // code here 9 | priority_queue, vector>, greater<>> minheap; 10 | 11 | for(int i = 0; i < points.size(); ++i) { 12 | int distance = points[i][0] * points[i][0] + points[i][1] * points[i][1]; 13 | 14 | minheap.push({distance, i}); 15 | } 16 | 17 | // while(!minheap.empty()) { 18 | // cout << minheap.top().first << "->" << minheap.top().second << " "; 19 | // minheap.pop(); 20 | // } 21 | 22 | vector> result; 23 | for(int i = 0; i < k; ++i) { 24 | auto pair = minheap.top(); 25 | minheap.pop(); 26 | result.push_back(points[pair.second]); 27 | } 28 | 29 | return result; 30 | } 31 | }; -------------------------------------------------------------------------------- /LoopLengthLL.cpp: -------------------------------------------------------------------------------- 1 | struct Node 2 | { 3 | int data; 4 | struct Node *next; 5 | Node(int x) 6 | { 7 | data = x; 8 | next = nullptr; 9 | } 10 | }; 11 | 12 | class Solution 13 | { 14 | public: 15 | // Function to find the length of a loop in the linked list. 16 | int countNodesinLoop(Node *head) 17 | { 18 | // Code here 19 | bool cycleFound = false; 20 | 21 | Node *fast = head; 22 | Node *slow = head; 23 | 24 | while (fast && fast->next) 25 | { 26 | fast = fast->next->next; 27 | slow = slow->next; 28 | if (fast == slow) 29 | { 30 | cycleFound = true; 31 | break; 32 | } 33 | } 34 | 35 | if (cycleFound) 36 | { 37 | int length = 0; 38 | do 39 | { 40 | fast = fast->next; 41 | ++length; 42 | } while (fast != slow); 43 | return length; 44 | } 45 | else 46 | { 47 | return 0; 48 | } 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /160/day12.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | class Solution { 6 | public: 7 | int maxCircularSum(std::vector &arr) { 8 | // code here 9 | int totalSum = 0; 10 | 11 | int currentMaxSum = 0; 12 | int currentMinSum = 0; 13 | 14 | int maxSumAnswer = INT_MIN; 15 | int minSumAnswer = INT_MAX; 16 | 17 | for(int x : arr) 18 | { 19 | totalSum += x; 20 | 21 | currentMaxSum += x; 22 | currentMaxSum = std::max(currentMaxSum, x); 23 | maxSumAnswer = std::max(maxSumAnswer, currentMaxSum); 24 | 25 | currentMinSum += x; 26 | currentMinSum = std::min(currentMinSum, x); 27 | minSumAnswer = std::min(minSumAnswer, currentMinSum); 28 | } 29 | 30 | int normalSum = maxSumAnswer; 31 | int circularSum = totalSum - minSumAnswer; 32 | 33 | if(minSumAnswer == totalSum) return normalSum; 34 | 35 | 36 | 37 | return std::max(circularSum, normalSum); 38 | } 39 | }; -------------------------------------------------------------------------------- /160/day17.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | char nonRepeatingChar(string &s) { 8 | // code here 9 | vector arr(26, -1); 10 | int n = s.size(); 11 | 12 | // -1 if the element is never seen 13 | // index i if element is seen only once 14 | // -2 if its repeating 15 | 16 | for(int i = 0; i < n; ++i) 17 | { 18 | char c = s[i]; 19 | 20 | if(arr[c - 'a'] == -1) 21 | { 22 | arr[c - 'a'] = i; 23 | } 24 | else if(arr[c - 'a'] >= 0) 25 | { 26 | arr[c - 'a'] = -2; 27 | } 28 | } 29 | char answer = '$'; 30 | int minIndex = n; 31 | 32 | for(int i = 0; i < 26; ++i) 33 | { 34 | if(arr[i] >= 0 && arr[i] < minIndex) 35 | { 36 | minIndex = arr[i]; 37 | answer = (char)(i + 'a'); 38 | } 39 | } 40 | 41 | return answer; 42 | } 43 | }; -------------------------------------------------------------------------------- /SortLL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | struct Node 5 | { 6 | int data; 7 | struct Node *next; 8 | Node(int x) 9 | { 10 | data = x; 11 | next = NULL; 12 | } 13 | }; 14 | 15 | class Solution 16 | { 17 | public: 18 | Node *segregate(Node *head) 19 | { 20 | // code here 21 | vector map(3, 0); 22 | 23 | Node *current = head; 24 | 25 | while (current) 26 | { 27 | map.at(current->data) += 1; 28 | current = current->next; 29 | } 30 | 31 | current = head; 32 | while (map.at(0) > 0) 33 | { 34 | current->data = 0; 35 | current = current->next; 36 | map.at(0)--; 37 | } 38 | while (map.at(1) > 0) 39 | { 40 | current->data = 1; 41 | current = current->next; 42 | map.at(1)--; 43 | } 44 | while (map.at(2) > 0) 45 | { 46 | current->data = 2; 47 | current = current->next; 48 | map.at(2)--; 49 | } 50 | 51 | return head; 52 | } 53 | }; -------------------------------------------------------------------------------- /MayPOTD/LargestNumberInKSwaps.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution 5 | { 6 | public: 7 | string findMaximumNum(string &s, int k) 8 | { 9 | string maxs = s; 10 | dfs(s, k, 0, maxs); 11 | return maxs; 12 | } 13 | 14 | private: 15 | void dfs(string &s, int k, int idx, string &maxs) 16 | { 17 | if (k == 0 || idx >= (int)s.size() - 1) 18 | return; 19 | char mx = s[idx]; 20 | for (int i = idx + 1; i < (int)s.size(); ++i) 21 | if (s[i] > mx) 22 | mx = s[i]; 23 | if (mx != s[idx]) 24 | { 25 | for (int i = s.size() - 1; i > idx; --i) 26 | { 27 | if (s[i] == mx) 28 | { 29 | swap(s[idx], s[i]); 30 | if (s > maxs) 31 | maxs = s; 32 | dfs(s, k - 1, idx + 1, maxs); 33 | swap(s[idx], s[i]); 34 | } 35 | } 36 | } 37 | else 38 | { 39 | dfs(s, k, idx + 1, maxs); 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /MaxSumOfNonAdjacentNodes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | // Node Structure 4 | 5 | 6 | struct Node 7 | { 8 | int data; 9 | Node* left; 10 | Node* right; 11 | }; 12 | 13 | 14 | class Solution { 15 | public: 16 | // Function to return the maximum sum of non-adjacent nodes. 17 | int getMaxSum(Node *root) { 18 | // code here 19 | std::pair answer = solve(root); 20 | 21 | return std::max(answer.first, answer.second); 22 | } 23 | 24 | private: 25 | 26 | // this returns a pair having sums of if we include that node and if we exclude that node 27 | std::pair solve(Node* root) { 28 | 29 | if(!root) return {0,0}; 30 | 31 | // left child 32 | std::pair left = solve(root->left); 33 | // right child 34 | std::pair right = solve(root->right); 35 | 36 | // for the current node 37 | int include = root->data + left.second + right.second; 38 | int exclude = std::max(left.first, left.second) + std::max(right.first, right.second); 39 | 40 | return {include, exclude}; 41 | 42 | } 43 | 44 | }; 45 | 46 | -------------------------------------------------------------------------------- /MayPOTD/LeftViewBinaryTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::vector; 4 | 5 | struct Node 6 | { 7 | int data; 8 | struct Node *left; 9 | struct Node *right; 10 | 11 | Node(int x) 12 | { 13 | data = x; 14 | left = right = NULL; 15 | } 16 | }; 17 | 18 | class Solution 19 | { 20 | public: 21 | vector leftView(Node *root) 22 | { 23 | // code here 24 | if(!root) { 25 | return {}; 26 | } 27 | 28 | std::queue q; 29 | q.push(root); 30 | 31 | vector result; 32 | while(!q.empty()) 33 | { 34 | int size = q.size(); 35 | for(int i = 0; i < size; ++i) { 36 | Node* front = q.front(); 37 | q.pop(); 38 | 39 | if(i == 0) { 40 | result.push_back(front->data); 41 | } 42 | if(front->left) { 43 | q.push(front->left); 44 | } 45 | if(front->right) { 46 | q.push(front->right); 47 | } 48 | } 49 | } 50 | return result; 51 | } 52 | }; -------------------------------------------------------------------------------- /MayPOTD/InsertInSortedCircularLinkedList.cpp: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Node { 4 | public: 5 | int data; 6 | Node *next; 7 | 8 | Node(int x){ 9 | data = x; 10 | next = nullptr; 11 | } 12 | }; 13 | 14 | class Solution { 15 | public: 16 | Node* sortedInsert(Node* head, int data) { 17 | // code here 18 | 19 | Node* newNode = new Node(data); 20 | 21 | if(head->data >= data) { 22 | 23 | Node* current = head; 24 | 25 | while(current->next != head) { 26 | current = current->next; 27 | } 28 | current->next = newNode; 29 | newNode->next = head; 30 | head = newNode; 31 | return head; 32 | 33 | } 34 | 35 | Node* current = head; 36 | while(current->next != head && current->next->data <= data) { 37 | current = current->next; 38 | } 39 | 40 | if(current->next == head) { 41 | current->next = newNode; 42 | newNode->next = head; 43 | return head; 44 | } 45 | 46 | newNode->next = current->next; 47 | current->next = newNode; 48 | return head; 49 | 50 | } 51 | }; -------------------------------------------------------------------------------- /BellmanFord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution { 5 | public: 6 | vector bellmanFord(int V, vector>& edges, int src) { 7 | // Code here 8 | vector dist(V, 1e8); 9 | dist[src] = 0; 10 | 11 | for(int i = 0; i < V-1; ++i) 12 | { 13 | for(auto edge : edges) 14 | { 15 | int u = edge[0]; 16 | int v = edge[1]; 17 | int w = edge[2]; 18 | 19 | if(dist[u] != 1e8 && dist[v] > dist[u] + w) 20 | { 21 | dist[v] = dist[u] + w; 22 | } 23 | } 24 | } 25 | // if after v-1 iterations i can still relax an edge thats the cycle 26 | 27 | for(auto edge : edges) 28 | { 29 | int u = edge[0]; 30 | int v = edge[1]; 31 | int w = edge[2]; 32 | 33 | if(dist[u] != 1e8 && dist[u] + w < dist[v]) 34 | { 35 | return {-1}; 36 | } 37 | } 38 | 39 | return dist; 40 | 41 | } 42 | }; -------------------------------------------------------------------------------- /160/day24.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | bool compare(const vector& a, const vector& b) { 8 | return a[0] < b [0]; 9 | } 10 | 11 | class Solution { 12 | public: 13 | vector> mergeOverlap(vector>& arr) { 14 | // Code here 15 | sort(arr.begin(), arr.end(), compare); 16 | vector> result; 17 | result.push_back({arr[0][0], arr[0][1]}); 18 | 19 | for(int i = 1; i < arr.size(); ++i) { 20 | vector interval = arr[i]; 21 | vector lastAddedInterval = result.back(); 22 | 23 | if(interval[0] <= lastAddedInterval[1]) { 24 | 25 | result.back().at(1) = max(lastAddedInterval[1], interval[1]); 26 | 27 | } else { 28 | result.push_back(interval); 29 | } 30 | } 31 | return result; 32 | } 33 | 34 | }; 35 | 36 | 37 | int main() 38 | { 39 | vector> arr = {{6, 8}, {1, 9}, {2, 4}, {4, 7}}; 40 | Solution s; 41 | auto result = s.mergeOverlap(arr); 42 | for(auto pair : result) { 43 | cout << pair[0] << " -> " << pair[1] << '\n'; 44 | } 45 | } -------------------------------------------------------------------------------- /MayPOTD/SmallestDistinctWindow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | class Solution 9 | { 10 | public: 11 | int findSubString(string &str) 12 | { 13 | // code here 14 | unordered_map map; 15 | unordered_set uniqueCharacters(str.begin(), str.end()); 16 | 17 | int required = uniqueCharacters.size(); 18 | 19 | int left = 0; 20 | int right = 0; 21 | int formed = 0; 22 | 23 | int result = INT_MAX; 24 | 25 | while (right < str.length()) 26 | { 27 | char ch = str[right]; 28 | map[ch]++; 29 | 30 | if (map[ch] == 1) 31 | { 32 | formed++; 33 | } 34 | 35 | while (formed == required) 36 | { 37 | result = min(result, right - left + 1); 38 | 39 | char leftch = str[left]; 40 | map[leftch]--; 41 | if (map[leftch] == 0) 42 | { 43 | --formed; 44 | } 45 | ++left; 46 | } 47 | 48 | ++right; 49 | } 50 | return result; 51 | } 52 | }; -------------------------------------------------------------------------------- /BridgeEdge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class Solution { 6 | public: 7 | bool isBridge(int V, vector> &edges, int c, int d) { 8 | // Code here 9 | unordered_map> adj; 10 | 11 | for(auto edgePair : edges) { 12 | if(edgePair[0] == c && edgePair[1] == d) continue; 13 | if(edgePair[1] == c && edgePair[0] == d) continue; 14 | 15 | adj[edgePair[0]].push_back(edgePair[1]); 16 | adj[edgePair[1]].push_back(edgePair[0]); 17 | } 18 | 19 | vector visited(V, false); 20 | 21 | // int visitedNodes = 0; 22 | stack st; 23 | st.push(c); 24 | visited[c] = true; 25 | 26 | while(!st.empty()) { 27 | int top = st.top(); 28 | st.pop(); 29 | for(auto neighbor : adj[top]) 30 | { 31 | if(!visited[neighbor]) { 32 | visited[neighbor] = true; 33 | st.push(neighbor); 34 | } 35 | } 36 | } 37 | 38 | 39 | return !visited[d]; 40 | } 41 | }; -------------------------------------------------------------------------------- /IsHeap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class Node 4 | { 5 | public: 6 | int data; 7 | Node *left; 8 | Node *right; 9 | 10 | Node(int val) 11 | { 12 | data = val; 13 | left = right = NULL; 14 | } 15 | }; 16 | 17 | class Solution 18 | { 19 | public: 20 | bool isHeap(Node *tree) 21 | { 22 | // code here 23 | std::queue q; 24 | q.push(tree); 25 | 26 | bool nullFound = false; 27 | 28 | while (!q.empty()) 29 | { 30 | Node *current = q.front(); 31 | q.pop(); 32 | 33 | if (current->left) 34 | { 35 | if (nullFound || current->data < current->left->data) 36 | return false; 37 | q.push(current->left); 38 | } 39 | else 40 | { 41 | nullFound = true; 42 | } 43 | 44 | if (current->right) 45 | { 46 | if (nullFound || current->data < current->right->data) 47 | return false; 48 | q.push(current->right); 49 | } 50 | else 51 | { 52 | nullFound = true; 53 | } 54 | } 55 | 56 | return true; 57 | } 58 | }; -------------------------------------------------------------------------------- /160/day25.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::max, std::vector; 3 | 4 | class Solution { 5 | public: 6 | vector> insertInterval(vector> &intervals, 7 | vector &newInterval) { 8 | // code here 9 | vector> result; 10 | int newStart = newInterval[0]; 11 | int newEnd = newInterval[1]; 12 | int n = intervals.size(); 13 | 14 | int i = 0; 15 | 16 | while(i < n && newStart >= intervals[i][0]) { 17 | result.push_back({intervals[i][0], intervals[i][1]}); 18 | ++i; 19 | } 20 | 21 | 22 | if(!result.empty() &&newStart <= result.back().at(1)) { 23 | result.back().at(1) = max(newEnd, result.back().at(1)); 24 | } 25 | else { 26 | result.push_back({newStart, newEnd}); 27 | } 28 | 29 | while(i < n && intervals[i][0] <= result.back().at(1)) { 30 | result.back().at(1) = max(result.back().at(1), intervals[i][1]); 31 | ++i; 32 | } 33 | 34 | while(i < n) 35 | { 36 | result.push_back({intervals[i][0], intervals[i][1]}); 37 | ++i; 38 | } 39 | 40 | return result; 41 | } 42 | }; -------------------------------------------------------------------------------- /160/day19.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | class Solution { 8 | public: 9 | int minChar(string &s) { 10 | // code here 11 | 12 | int n = s.length(); 13 | 14 | string reversed = s; 15 | reverse(reversed.begin(), reversed.end()); 16 | 17 | string pattern = s + "$" + reversed; 18 | 19 | vector lps = createLPS(pattern); 20 | return n - lps.back(); 21 | 22 | } 23 | private: 24 | vector createLPS(string &pattern) { 25 | 26 | int n = pattern.size(); 27 | int len = 0; 28 | vector lps(n); 29 | 30 | lps[0] = 0; 31 | int i = 1; 32 | while(i < n) 33 | { 34 | if(pattern[len] != pattern[i] && len == 0) 35 | { 36 | lps[i] = 0; 37 | ++i; 38 | } 39 | else if(pattern[len] != pattern[i] && len > 0) 40 | { 41 | len = lps[len - 1]; 42 | } 43 | else if(pattern[len] == pattern[i]) 44 | { 45 | ++len; 46 | lps[i] = len; 47 | ++i; 48 | } 49 | } 50 | return lps; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /RotateArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | 8 | // Function to rotate an array by d elements in counter-clockwise direction. 9 | void rotateArr(vector& arr, int d) { 10 | int n = arr.size(); 11 | 12 | 13 | // one brute force way to solve this is by manually deleting first d elements and appending them to the last, that however takes extra time and space. 14 | // there is a more elegant and efficient solution 15 | 16 | int rotations = d % n; 17 | if(!rotations) return; 18 | 19 | reverseArray(arr, 0, rotations-1); 20 | reverseArray(arr, rotations, n-1); 21 | reverseArray(arr, 0, n-1); 22 | 23 | 24 | 25 | // code here 26 | } 27 | 28 | private: 29 | void reverseArray(vector &arr, int left, int right) { 30 | int l = left; 31 | int r = right; 32 | 33 | while(l < r) { 34 | int t = arr[l]; 35 | arr[l] = arr[r]; 36 | arr[r] = t; 37 | ++l; 38 | --r; 39 | } 40 | } 41 | 42 | 43 | 44 | }; -------------------------------------------------------------------------------- /MayPOTD/PrimeList.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Node 3 | { 4 | public: 5 | int val; 6 | Node *next; 7 | Node(int num) 8 | { 9 | val = num; 10 | next = nullptr; 11 | } 12 | }; 13 | 14 | class Solution 15 | { 16 | public: 17 | Node *primeList(Node *head) 18 | { 19 | // code here 20 | 21 | Node *current = head; 22 | while (current) 23 | { 24 | current->val = findNearestPrime(current->val); 25 | current = current->next; 26 | } 27 | 28 | return head; 29 | } 30 | 31 | private: 32 | bool isPrime(int n) 33 | { 34 | if (n < 2) 35 | return false; 36 | 37 | for (int i = 2; i * i <= n; ++i) 38 | { 39 | if (n % i == 0) 40 | return false; 41 | } 42 | 43 | return true; 44 | } 45 | 46 | int findNearestPrime(int n) 47 | { 48 | if (isPrime(n)) 49 | return n; 50 | 51 | int forward = n + 1; 52 | int backward = n - 1; 53 | 54 | while (true) 55 | { 56 | if (isPrime(backward)) 57 | { 58 | return backward; 59 | } 60 | if (isPrime(forward)) 61 | { 62 | return forward; 63 | } 64 | forward++; 65 | backward--; 66 | } 67 | } 68 | }; -------------------------------------------------------------------------------- /UniqueNumberII.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution { 5 | public: 6 | vector singleNum(vector& arr) { 7 | // Code here. 8 | 9 | int total = 0; 10 | for(int x : arr) { 11 | total ^= x; 12 | } 13 | // calculate the total XOR sum of the array, this is essentially the XOR of two distinct elements; 14 | 15 | int rightmostBit = total & -total; // the rightmost bit which differs between the two distinct integers; 16 | 17 | int firstNumber = 0; // xor sum of the elements which have the differing rightmost bit set; 18 | int secondNumber = 0; // xor sum of the elements which have the differing rightmost bit not set; 19 | 20 | for(int x : arr) { 21 | if(x & rightmostBit) { // check if the bit is set 22 | firstNumber ^= x; 23 | } 24 | else { 25 | secondNumber ^= x; 26 | } 27 | } 28 | 29 | 30 | vector result(2); 31 | if(firstNumber < secondNumber){ 32 | result[0] = firstNumber; 33 | result[1] = secondNumber; 34 | } 35 | else { 36 | result[0] = secondNumber; 37 | result[1] = firstNumber; 38 | } 39 | 40 | return result; 41 | 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /MoveAllZeroesToEnd.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | void pushZerosToEnd(vector& arr) { 8 | int n = arr.size(); 9 | int j = 0; 10 | for(int i = 0; i < n; ++i) { 11 | 12 | // i and j both move forward if its a non zero element; 13 | 14 | if(arr[i] != 0) { 15 | swap(arr[i], arr[j]); 16 | j++; 17 | } 18 | 19 | // if a zero element is there only i moves forward and next time i is on a non zero element it is swapped with j which is still on the zero element; 20 | } 21 | } 22 | // Time Complexity - O(n) 23 | // Space Complexity - O(1) 24 | private: 25 | void swap(int &a, int &b) { 26 | int t = a; 27 | a = b; 28 | b = t; 29 | } 30 | }; 31 | 32 | 33 | int main() { 34 | Solution solution; 35 | vector arr = {1, 2, 0, 4, 3, 0, 5, 0}; 36 | 37 | cout << "Original array: "; 38 | for (int i : arr) { 39 | cout << i << " "; 40 | } 41 | cout << endl; 42 | 43 | solution.pushZerosToEnd(arr); 44 | 45 | cout << "Array after pushing zeros to the end: "; 46 | for (int i : arr) { 47 | cout << i << " "; 48 | } 49 | cout << endl; 50 | 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /TopologicalSort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class Solution { 6 | 7 | unordered_map> adj; 8 | 9 | void dfs(int source, vector &visited, stack &answer) { 10 | 11 | for(auto neighbor : adj[source]) { 12 | 13 | if(!visited[neighbor]) { 14 | visited[neighbor] = true; 15 | dfs(neighbor, visited, answer); 16 | } 17 | } 18 | 19 | answer.push(source); 20 | } 21 | 22 | public: 23 | vector topoSort(int V, vector>& edges) { 24 | // code here 25 | 26 | for(auto edgePair : edges) { 27 | adj[edgePair[0]].push_back(edgePair[1]); 28 | } 29 | 30 | vector visited(V, false); 31 | 32 | stack answer; 33 | 34 | for(int i = 0; i < V; ++i) { 35 | if(!visited[i]) { 36 | visited[i] = true; 37 | dfs(i, visited, answer); 38 | } 39 | } 40 | 41 | vector result; 42 | while(!answer.empty()) 43 | { 44 | result.push_back(answer.top()); 45 | answer.pop(); 46 | } 47 | 48 | // for(int i : result) { 49 | // cout << i << " "; 50 | // } 51 | 52 | return result; 53 | 54 | } 55 | }; -------------------------------------------------------------------------------- /DirectedGraphCycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // kahn's algorithm 6 | 7 | class Solution { 8 | public: 9 | bool isCyclic(int V, vector> &edges) { 10 | // code here 11 | unordered_map> adj; 12 | 13 | vector indegree(V, 0); 14 | 15 | for(auto edgePair : edges) { 16 | adj[edgePair[0]].push_back(edgePair[1]); 17 | indegree[edgePair[1]]++; 18 | } 19 | 20 | // for(int i : indegree) { 21 | // cout << i << " "; 22 | // } 23 | 24 | queue q; 25 | for(int i = 0; i < V; ++i) { 26 | if(indegree[i] == 0) { 27 | q.push(i); 28 | } 29 | } 30 | 31 | 32 | 33 | int processed = 0; 34 | 35 | while(!q.empty()) 36 | { 37 | int front = q.front(); 38 | q.pop(); 39 | ++processed; 40 | 41 | for(auto neighbor : adj[front]) { 42 | if(indegree[neighbor] == 0) continue; 43 | indegree[neighbor]--; 44 | if(indegree[neighbor] == 0) { 45 | q.push(neighbor); 46 | } 47 | } 48 | } 49 | 50 | return processed < V; 51 | 52 | } 53 | }; -------------------------------------------------------------------------------- /FloodFillAlgorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Flood Fill Algorithm 5 | class Solution 6 | { 7 | public: 8 | vector> floodFill(vector> &image, int sr, int sc, 9 | int newColor) 10 | { 11 | int n = image.size(); 12 | int m = image[0].size(); 13 | 14 | queue> q; 15 | vector> visited(n, vector(m, false)); 16 | vector> directions = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}}; 17 | 18 | int pixel = image[sr][sc]; 19 | visited[sr][sc] = true; 20 | q.push(make_pair(sr, sc)); 21 | 22 | while (!q.empty()) 23 | { 24 | pair front = q.front(); 25 | int x = front.first; 26 | int y = front.second; 27 | image[x][y] = newColor; 28 | q.pop(); 29 | 30 | for (auto direction : directions) 31 | { 32 | int dx = direction.first; 33 | int dy = direction.second; 34 | 35 | int nx = x + dx; 36 | int ny = y + dy; 37 | 38 | if (nx >= 0 && nx < n && ny >= 0 && ny < m && !visited[nx][ny] && image[nx][ny] == pixel) 39 | { 40 | visited[nx][ny] = true; 41 | q.push(make_pair(nx, ny)); 42 | } 43 | } 44 | } 45 | return image; 46 | } 47 | }; -------------------------------------------------------------------------------- /MayPOTD/LevelOrderSpiral.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::vector; 4 | 5 | class Node 6 | { 7 | public: 8 | int data; 9 | Node* left; 10 | Node* right; 11 | 12 | Node(int x){ 13 | data = x; 14 | left = right = NULL; 15 | } 16 | }; 17 | 18 | class Solution { 19 | public: 20 | vector findSpiral(Node* root) { 21 | // code here 22 | vector result; 23 | 24 | std::stack s1; // left to right; 25 | std::stack s2; // right to left; 26 | 27 | s1.push(root); 28 | 29 | while(!s1.empty() || !s2.empty()) { 30 | 31 | while(!s2.empty()) { 32 | Node* top = s2.top(); 33 | s2.pop(); 34 | result.push_back(top->data); 35 | if(top->left) { 36 | s1.push(top->left); 37 | } 38 | if(top->right) { 39 | s1.push(top->right); 40 | } 41 | } 42 | 43 | while(!s1.empty()) { 44 | Node* top = s1.top(); 45 | s1.pop(); 46 | result.push_back(top->data); 47 | 48 | if(top->right) { 49 | s2.push(top->right); 50 | } 51 | 52 | if(top->left) { 53 | s2.push(top->left); 54 | } 55 | } 56 | 57 | } 58 | 59 | return result; 60 | } 61 | }; -------------------------------------------------------------------------------- /CountIslands.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | 8 | vector> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}, {1, 1}, {-1, -1}, {1, -1}, {-1, 1}}; 9 | 10 | void dfs(vector> &grid, int i , int j, vector> &visited) { 11 | 12 | 13 | if(grid[i][j] == 'W') return; 14 | 15 | visited[i][j] = true; 16 | 17 | for(auto direction : directions) { 18 | 19 | int dx = direction.first; 20 | int dy = direction.second; 21 | 22 | int nx = i + dx; 23 | int ny = j + dy; 24 | 25 | if(nx >= 0 && nx < grid.size() && ny >= 0 && ny < grid[0].size() && !visited[nx][ny]) { 26 | dfs(grid, nx, ny, visited); 27 | } 28 | } 29 | 30 | } 31 | 32 | int countIslands(vector>& grid) { 33 | // Code here 34 | 35 | int n = grid.size(); 36 | int m = grid[0].size(); 37 | 38 | vector> visited(n, vector(m, false)); 39 | 40 | int islandCount = 0; 41 | 42 | for(int i = 0; i < n; ++i) { 43 | for(int j = 0; j < m; ++j) { 44 | // for each cell with L visit all possible L and mark them visited 45 | if(grid[i][j] == 'L' && !visited[i][j]) { 46 | dfs(grid, i, j, visited); 47 | ++islandCount; 48 | } 49 | } 50 | } 51 | 52 | return islandCount; 53 | 54 | 55 | } 56 | }; -------------------------------------------------------------------------------- /TrieImplementation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class TrieNode 6 | { 7 | public: 8 | unordered_map children; 9 | bool isEndOfWord; 10 | 11 | TrieNode() 12 | { 13 | isEndOfWord = false; 14 | } 15 | }; 16 | 17 | class Trie 18 | { 19 | private: 20 | TrieNode *root; 21 | 22 | public: 23 | Trie() 24 | { 25 | root = new TrieNode(); 26 | } 27 | 28 | void insert(string &word) 29 | { 30 | TrieNode *current = root; 31 | for (char c : word) 32 | { 33 | if (current->children.find(c) == current->children.end()) 34 | { 35 | current->children[c] = new TrieNode(); 36 | } 37 | current = current->children[c]; 38 | } 39 | current->isEndOfWord = true; 40 | } 41 | 42 | bool search(string &word) 43 | { 44 | TrieNode *current = root; 45 | for (char c : word) 46 | { 47 | if (current->children.find(c) == current->children.end()) 48 | { 49 | return false; 50 | } 51 | current = current->children[c]; 52 | } 53 | return current->isEndOfWord; 54 | } 55 | 56 | bool isPrefix(string &word) 57 | { 58 | TrieNode *current = root; 59 | for (char c : word) 60 | { 61 | if (current->children.find(c) == current->children.end()) 62 | { 63 | return false; 64 | } 65 | current = current->children[c]; 66 | } 67 | return true; 68 | } 69 | }; -------------------------------------------------------------------------------- /160/day20.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | bool areRotations(string &s1, string &s2) { 8 | // code here 9 | string text = s2 + s2; 10 | string pattern = s1; 11 | return KMP(text, pattern); 12 | } 13 | private: 14 | vector createLPS(string& pattern) { 15 | int n = pattern.size(); 16 | vector lps(n); 17 | int len = 0; 18 | lps[0] = 0; 19 | int i = 1; 20 | while(i < n) { 21 | if(pattern[len] != pattern[i] && len == 0) { 22 | lps[i] = 0; 23 | ++i; 24 | } 25 | else if(pattern[len] != pattern[i] && len > 0) { 26 | len = lps[len - 1]; 27 | } 28 | else if(pattern[len] == pattern[i]) { 29 | ++len; 30 | lps[i] = len; 31 | ++i; 32 | } 33 | } 34 | return lps; 35 | } 36 | 37 | bool KMP(string &text, string &pattern) { 38 | int i = 0; 39 | int j = 0; 40 | 41 | vector lps = createLPS(pattern); 42 | 43 | while(i < text.size()) 44 | { 45 | if(text[i] == pattern[j]) { 46 | ++i; 47 | ++j; 48 | } 49 | else { 50 | if(j > 0) { 51 | j = lps[j-1]; 52 | } else { 53 | ++i; 54 | } 55 | } 56 | if(j == pattern.size()) return true; 57 | } 58 | return false; 59 | 60 | } 61 | 62 | }; -------------------------------------------------------------------------------- /160/day18.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | vector createLPS(string &pattern) { 7 | int n = pattern.size(); 8 | vector lps(n); 9 | int len = 0; 10 | 11 | lps[0] = 0; 12 | 13 | int i = 1; 14 | while(i < n) 15 | { 16 | if(pattern[len] != pattern[i] && len == 0) 17 | { 18 | lps[i] = 0; 19 | ++i; 20 | } 21 | else if(pattern[len] != pattern[i] && len > 0) 22 | { 23 | len = lps[len - 1]; 24 | } 25 | else if(pattern[len] == pattern[i]) 26 | { 27 | ++len; 28 | lps[i] = len; 29 | ++i; 30 | } 31 | 32 | } 33 | 34 | return lps; 35 | } 36 | 37 | vector KMP(string &text, string &pattern) { 38 | vector result; 39 | vector lps = createLPS(pattern); 40 | 41 | int i = 0; 42 | int j = 0; 43 | 44 | while(i < text.length()) 45 | { 46 | if(text[i] == pattern[j]) 47 | { 48 | ++i; 49 | ++j; 50 | } 51 | else 52 | { 53 | if(j != 0) 54 | j = lps[j - 1]; 55 | else ++i; 56 | } 57 | 58 | if(j == pattern.length()) 59 | { 60 | result.push_back(i - j); 61 | j = lps[j - 1]; 62 | } 63 | } 64 | 65 | return result; 66 | } 67 | 68 | int main() { 69 | string text = "aabaacaadaabaaba"; 70 | string pattern = "aaba"; 71 | 72 | vector result = KMP(text, pattern); 73 | for(int i : result) 74 | { 75 | cout << i << " "; 76 | } 77 | return 0; 78 | } -------------------------------------------------------------------------------- /MajorityElementII.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution { 5 | public: 6 | // Function to find the majority elements in the array 7 | vector findMajority(vector& arr) { 8 | // Your code goes here. 9 | 10 | 11 | // the extended boyer moore voting algo for 2 candidates 12 | 13 | 14 | int n = arr.size(); 15 | 16 | int cand1 = 0; 17 | int cand2 = 0; 18 | int count1 = 0; 19 | int count2 = 0; 20 | 21 | for(int i : arr) { 22 | if(i == cand1) { 23 | ++count1; 24 | } 25 | else if(i == cand2) { 26 | ++count2; 27 | } 28 | else if(count1 == 0) { 29 | cand1 = i; 30 | count1 = 1; 31 | } 32 | else if(count2 == 0) { 33 | cand2 = i; 34 | count2 = 1; 35 | } 36 | else { 37 | count1--; 38 | count2--; 39 | } 40 | } 41 | 42 | count1 = 0; 43 | count2 = 0; 44 | 45 | for(int i : arr) { 46 | if(i == cand1) ++count1; 47 | else if(i == cand2) ++count2; 48 | } 49 | 50 | vector result; 51 | if(count1 > n/3) { 52 | result.push_back(cand1); 53 | } 54 | if(count2 > n/3) { 55 | result.push_back(cand2); 56 | } 57 | sort(result.begin(), result.end()); 58 | return result; 59 | } 60 | }; -------------------------------------------------------------------------------- /StringMultiplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using std::string, std::vector; 4 | 5 | class Solution 6 | { 7 | public: 8 | /*You are required to complete below function */ 9 | string multiplyStrings(string &s1, string &s2) 10 | { 11 | // Your code here 12 | if (s1 == "0" || s2 == "0") 13 | return "0"; 14 | 15 | bool isPositive = true; 16 | if ((s1[0] == '-' && s2[0] != '-') || (s1[0] != '-' && s2[0] == '-')) 17 | { 18 | isPositive = false; 19 | } 20 | 21 | if (s1[0] == '-') 22 | s1 = s1.substr(1); 23 | if (s2[0] == '-') 24 | s2 = s2.substr(1); 25 | 26 | int n = s1.length(); 27 | int m = s2.length(); 28 | 29 | vector result(n + m, 0); 30 | for (int i = n - 1; i >= 0; --i) 31 | { 32 | for (int j = m - 1; j >= 0; --j) 33 | { 34 | int product = (s1[i] - '0') * (s2[j] - '0'); 35 | int pos1 = i + j; 36 | int pos2 = i + j + 1; 37 | int sum = product + result[pos2]; 38 | 39 | result[pos2] = sum % 10; 40 | result[pos1] += sum / 10; 41 | } 42 | } 43 | string output = ""; 44 | for (int i = 0; i < result.size(); ++i) 45 | { 46 | if (!(output.empty() && result[i] == 0)) 47 | { 48 | output += std::to_string(result[i]); 49 | } 50 | } 51 | if (output.empty()) 52 | return "0"; 53 | 54 | if (!isPositive) 55 | { 56 | output = '-' + output; 57 | } 58 | 59 | return output; 60 | } 61 | }; -------------------------------------------------------------------------------- /MayPOTD/PredecessorAndSuccessor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using std::vector; 4 | 5 | class Node 6 | { 7 | public: 8 | int data; 9 | Node *left; 10 | Node *right; 11 | 12 | Node(int x) 13 | { 14 | data = x; 15 | left = NULL; 16 | right = NULL; 17 | } 18 | }; 19 | 20 | class Solution 21 | { 22 | public: 23 | vector findPreSuc(Node *root, int key) 24 | { 25 | // code here 26 | vector result(2, nullptr); 27 | Node *curr = root; 28 | 29 | while (curr) 30 | { 31 | if (curr->data == key) 32 | { 33 | 34 | if (curr->left) 35 | result[0] = findPre(curr->left); 36 | 37 | 38 | if (curr->right) 39 | result[1] = findSuc(curr->right); 40 | break; 41 | } 42 | else if (curr->data > key) 43 | { 44 | // Current node could be successor 45 | result[1] = curr; 46 | curr = curr->left; 47 | } 48 | else 49 | { 50 | // Current node could be predecessor 51 | result[0] = curr; 52 | curr = curr->right; 53 | } 54 | } 55 | 56 | return result; 57 | } 58 | 59 | private: 60 | Node *findPre(Node *root) 61 | { 62 | while (root->right) 63 | { 64 | root = root->right; 65 | } 66 | return root; 67 | } 68 | Node *findSuc(Node *root) 69 | { 70 | while (root->left) 71 | { 72 | root = root->left; 73 | } 74 | return root; 75 | } 76 | }; -------------------------------------------------------------------------------- /MayPOTD/SmallestRangeInKLists.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using std::vector, std::cout; 7 | 8 | typedef std::pair> PAIR; 9 | 10 | class Solution 11 | { 12 | public: 13 | vector findSmallestRange(vector> &arr) 14 | { 15 | // code here 16 | std::priority_queue, std::greater> minHeap; 17 | 18 | int k = arr.size(); // rows 19 | int n = arr.at(0).size(); // columns 20 | 21 | vector ans(2); 22 | 23 | int left = INT_MAX; 24 | int right = INT_MIN; 25 | int minRange = INT_MAX; 26 | 27 | for(int i = 0; i < k; ++i) { 28 | 29 | minHeap.push({arr[i][0], {i, 0}}); 30 | right = std::max(right, arr[i][0]); 31 | 32 | } 33 | 34 | while(1) { 35 | 36 | auto pair = minHeap.top(); 37 | minHeap.pop(); 38 | 39 | left = pair.first; 40 | 41 | auto indices = pair.second; 42 | int i = indices.first; 43 | int j = indices.second; 44 | 45 | int currentRange = right - left; 46 | 47 | if(currentRange < minRange) { 48 | minRange = currentRange; 49 | ans[0] = left; 50 | ans[1] = right; 51 | } 52 | 53 | j++; 54 | if(j >= n) break; 55 | 56 | right = std::max(right, arr[i][j]); 57 | minHeap.push({arr[i][j], {i, j}}); 58 | } 59 | return ans; 60 | } 61 | }; 62 | 63 | int main() { 64 | Solution s; 65 | vector> arr = {{4, 7, 9, 12, 15}, {0, 8, 10, 14, 20}, {6, 12, 16, 30, 50}}; 66 | vector ans = s.findSmallestRange(arr); 67 | cout << ans.at(0) << " " << ans.at(1); 68 | } -------------------------------------------------------------------------------- /UndirectedGraphCycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // the good old graph cycle detection problem. It can be solved traditionally by performing a traversal and checking if a node can be reached via two distinct parents. 6 | 7 | // a better way is using the disjoint set data structure (specifically the union and find operations) 8 | // since STL doesnt provide it i'll implement my own. 9 | 10 | class DisjointSetUnion { 11 | private: 12 | vector parent; 13 | 14 | public: 15 | DisjointSetUnion(int V) { 16 | 17 | parent.resize(V); 18 | 19 | for(int i = 0; i < V; ++i) { 20 | parent[i] = i; 21 | } 22 | } 23 | 24 | 25 | int find(int x) { 26 | while(x != parent[x]) { 27 | x = parent[x]; 28 | } 29 | return x; 30 | } 31 | 32 | 33 | int doUnion(int a, int b) { 34 | int parent1 = find(a); 35 | int parent2 = find(b); 36 | 37 | if(parent1 != parent2) { 38 | parent[parent1] = parent2; 39 | } 40 | } 41 | }; 42 | // nice 43 | 44 | 45 | class Solution { 46 | 47 | public: 48 | bool isCycle(int V, vector>& edges) { 49 | // Code here 50 | DisjointSetUnion set = DisjointSetUnion(V); 51 | for(auto edgePair: edges) { 52 | 53 | int parent1 = set.find(edgePair[0]); 54 | int parent2 = set.find(edgePair[1]); 55 | 56 | 57 | if(parent1 == parent2) { 58 | return true; 59 | } 60 | else { 61 | set.doUnion(parent1, parent2); 62 | } 63 | } 64 | return false; 65 | } 66 | 67 | // this solution is elegant indeed 68 | }; -------------------------------------------------------------------------------- /MaxXOR.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector, std::max; 3 | 4 | class TrieNode 5 | { 6 | public: 7 | TrieNode *children[2]; 8 | TrieNode() 9 | { 10 | children[0] = nullptr; 11 | children[1] = nullptr; 12 | } 13 | }; 14 | 15 | class Trie 16 | { 17 | private: 18 | TrieNode *root; 19 | 20 | public: 21 | Trie() 22 | { 23 | root = new TrieNode(); 24 | } 25 | 26 | void insert(int num) 27 | { 28 | TrieNode *node = root; 29 | for (int i = 31; i >= 0; i--) 30 | { 31 | int bit = (num >> i) & 1; 32 | if (!node->children[bit]) 33 | { 34 | node->children[bit] = new TrieNode(); 35 | } 36 | node = node->children[bit]; 37 | } 38 | } 39 | 40 | int findMaxXor(int num) 41 | { 42 | TrieNode *node = root; 43 | int maxXor = 0; 44 | for (int i = 31; i >= 0; i--) 45 | { 46 | int bit = (num >> i) & 1; 47 | int oppositeBit = 1 - bit; 48 | if (node->children[oppositeBit]) 49 | { 50 | maxXor = (maxXor << 1) | 1; 51 | node = node->children[oppositeBit]; 52 | } 53 | else 54 | { 55 | maxXor = (maxXor << 1) | 0; 56 | node = node->children[bit]; 57 | } 58 | } 59 | return maxXor; 60 | } 61 | }; 62 | 63 | class Solution 64 | { 65 | public: 66 | int maxXor(vector &arr) 67 | { 68 | Trie trie; 69 | int maxResult = 0; 70 | for (int num : arr) 71 | { 72 | trie.insert(num); 73 | } 74 | for (int num : arr) 75 | { 76 | int currentXor = trie.findMaxXor(num); 77 | maxResult = max(maxResult, currentXor); 78 | } 79 | return maxResult; 80 | } 81 | }; -------------------------------------------------------------------------------- /DijsktraAlgorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution { 5 | public: 6 | vector dijkstra(int V, vector> &edges, int src) { 7 | // Code here 8 | unordered_map>> adj; 9 | 10 | for(auto edge : edges) 11 | { 12 | int u = edge[0]; 13 | int v = edge[1]; 14 | int w = edge[2]; 15 | 16 | adj[u].push_back(make_pair(v, w)); 17 | adj[v].push_back(make_pair(u, w)); 18 | } 19 | 20 | unordered_map dist; 21 | 22 | for(int i = 0; i < V; ++i) { 23 | if(i == src) { 24 | dist[i] = 0; 25 | continue; 26 | } 27 | dist[i] = INT_MAX; 28 | } 29 | 30 | priority_queue, vector>, greater>> minHeap; 31 | minHeap.push(make_pair(0, src)); 32 | 33 | while(!minHeap.empty()) { 34 | pair top = minHeap.top(); 35 | minHeap.pop(); 36 | 37 | int node = top.second; 38 | 39 | for(auto edge : adj[node]) { 40 | int neighbor = edge.first; 41 | int weight = edge.second; 42 | 43 | if(dist[node] + weight < dist[neighbor]) { 44 | dist[neighbor] = dist[node] + weight; 45 | minHeap.push(make_pair(dist[neighbor], neighbor)); 46 | } 47 | } 48 | } 49 | 50 | vector result(V); 51 | for(int i = 0; i < V; ++i) { 52 | result[i] = dist[i]; 53 | } 54 | return result; 55 | 56 | 57 | } 58 | }; -------------------------------------------------------------------------------- /NextGreaterPermutation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | void nextPermutation(vector& arr) { 8 | int n = arr.size(); 9 | 10 | // code here 11 | // Step 1. find the rightmost element smaller than its next element 12 | int pivot = -1; 13 | 14 | for(int i = n-2; i >= 0; --i) 15 | { 16 | if(arr[i] < arr[i+1]) { 17 | pivot = i; 18 | break; 19 | } 20 | } 21 | // If there is no pivot that means , the array is sorted in descending order 22 | // Next Greater Permutation would be the array sorted in ascending order 23 | if(pivot == -1) { 24 | reverseArray(arr, 0, n-1); 25 | return; 26 | } 27 | 28 | // Step 2 - find the rightmost element greater than pivot element 29 | int rightmostGreater = -1; 30 | for(int i = n-1; i >= 0; --i) { 31 | if(arr[i] > arr[pivot]) { 32 | rightmostGreater = i; 33 | break; 34 | } 35 | } 36 | 37 | // Step 3 - swap the pivot and rightmost greater element 38 | swap(arr[pivot], arr[rightmostGreater]); 39 | 40 | // Step 4 - reverse the section from pivot + 1 to end. 41 | reverseArray(arr, pivot + 1, n-1); 42 | 43 | } 44 | // Time Complexity - O(n) 45 | // Space Complexity - O(1) 46 | 47 | private: 48 | void reverseArray(vector &arr, int start, int end) { 49 | while(start < end) { 50 | swap(arr[start++], arr[end--]); 51 | } 52 | } 53 | void swap(int &x, int &y) { 54 | int temp = x; 55 | x = y; 56 | y = temp; 57 | } 58 | }; -------------------------------------------------------------------------------- /MayPOTD/SortAfterTransformation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using std::vector; 3 | 4 | class Solution 5 | { 6 | public: 7 | vector sortArray(vector &arr, int A, int B, int C) 8 | { 9 | // code here 10 | int n = arr.size(); 11 | 12 | int left = 0; 13 | int right = n - 1; 14 | 15 | vector result(n); 16 | int resultIndex = A >= 0? n-1 : 0; 17 | 18 | while(left <= right) { 19 | int leftValue = transform(arr[left], A, B, C); 20 | int rightValue = transform(arr[right], A, B, C); 21 | 22 | if(A >= 0) // upward parabola - largest values are towards the end and minimum value is somewhere in middle. 23 | { 24 | // build the result from right to left as result should be sorted in ascending and largest values are at right. 25 | if(leftValue > rightValue) { 26 | result[resultIndex--] = leftValue; 27 | ++left; 28 | } 29 | else { 30 | result[resultIndex--] = rightValue; 31 | --right; 32 | } 33 | 34 | } 35 | else // downward parabola - smallest values are towards the end and maximum value is somewhere in middle 36 | { 37 | // build the result from left to right as smallest values are at left 38 | if(leftValue < rightValue) { 39 | result[resultIndex++] = leftValue; 40 | ++left; 41 | } 42 | else { 43 | result[resultIndex++] = rightValue; 44 | --right; 45 | } 46 | } 47 | } 48 | 49 | return result; 50 | // this was interesting 51 | } 52 | 53 | private: 54 | int transform(int x, int a, int b, int c) { 55 | return a*x*x + b*x + c; 56 | } 57 | 58 | }; -------------------------------------------------------------------------------- /MayPOTD/MeetingRoomsIII.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class Solution { 6 | public: 7 | int mostBooked(int n, vector> &meetings) { 8 | 9 | sort(meetings.begin(), meetings.end()); 10 | 11 | // Min-heap for free rooms (by room number) 12 | priority_queue, greater> free_rooms; 13 | for (int i = 0; i < n; ++i) { 14 | free_rooms.push(i); 15 | } 16 | 17 | // Min-heap for occupied rooms: (end_time, room_number) 18 | priority_queue, vector>, greater<>> ongoing; 19 | 20 | 21 | vector count(n, 0); 22 | 23 | for (auto &meeting : meetings) { 24 | long long start = meeting[0]; 25 | long long end = meeting[1]; 26 | 27 | // free up rooms where meetings have ended 28 | while (!ongoing.empty() && ongoing.top().first <= start) { 29 | int room = ongoing.top().second; 30 | ongoing.pop(); 31 | free_rooms.push(room); 32 | } 33 | 34 | if (!free_rooms.empty()) { 35 | int room = free_rooms.top(); 36 | free_rooms.pop(); 37 | ongoing.push({end, room}); 38 | count[room]++; 39 | } else { 40 | // no room is free; delay the meeting 41 | pair x = ongoing.top(); 42 | int avail_time = x.first; 43 | int room = x.second; 44 | 45 | ongoing.pop(); 46 | long long duration = end - start; 47 | ongoing.push({avail_time + duration, room}); 48 | count[room]++; 49 | } 50 | } 51 | 52 | 53 | int max_meetings = 0, result = 0; 54 | for (int i = 0; i < n; ++i) { 55 | if (count[i] > max_meetings) { 56 | max_meetings = count[i]; 57 | result = i; 58 | } 59 | } 60 | 61 | return result; 62 | } 63 | }; 64 | -------------------------------------------------------------------------------- /ArticulationPoints.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class Solution { 6 | public: 7 | 8 | void dfs(int u, int parent, unordered_map> &adj, 9 | vector &tin, vector &low, 10 | vector &visited, 11 | vector &isArticulation, 12 | int &timer 13 | ) 14 | { 15 | visited[u] = true; 16 | tin[u] = low[u] = timer++; 17 | int children = 0; 18 | 19 | for(int v : adj[u]) { 20 | if(v == parent) continue; 21 | if(visited[v]) { 22 | low[u] = min(low[u], tin[v]); 23 | } 24 | else { 25 | dfs(v, u, adj, tin, low, visited, isArticulation, timer); 26 | low[u] = min(low[u], low[v]); 27 | 28 | if(low[v] >= tin[u] && parent != -1) { 29 | isArticulation[u] = true; 30 | } 31 | ++children; 32 | } 33 | } 34 | if(parent == -1 && children > 1) { 35 | isArticulation[u] = true; 36 | } 37 | 38 | } 39 | 40 | vector articulationPoints(int V, vector>& edges) { 41 | // Code here 42 | 43 | unordered_map> adj; 44 | 45 | for(auto edgePair : edges) { 46 | int u = edgePair[0]; 47 | int v = edgePair[1]; 48 | 49 | adj[u].push_back(v); 50 | adj[v].push_back(u); 51 | } 52 | 53 | vector tin(V, -1), low(V, -1); 54 | vector visited(V, false); 55 | vector isArticulation(V, false); 56 | int timer = 0; 57 | for(int i = 0; i < V; ++i) { 58 | if(!visited[i]) { 59 | dfs(i, -1, adj, tin, low, visited, isArticulation, timer); 60 | } 61 | } 62 | 63 | vector result; 64 | for(int i = 0; i < V; ++i) { 65 | if(isArticulation[i]) result.push_back(i); 66 | } 67 | 68 | if(result.empty()) return {-1}; 69 | return result; 70 | } 71 | }; -------------------------------------------------------------------------------- /160/day14.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class Solution { 5 | public: 6 | bool safeToIncrease(int number, int ascii, bool isNegative) 7 | { 8 | if(isNegative) 9 | { 10 | return (number <= (INT_MAX - ascii + 49) / 10); 11 | } 12 | else 13 | { 14 | return (number <= (INT_MAX - ascii + 48) / 10); 15 | } 16 | } 17 | 18 | int myAtoi(std::string& s) { 19 | bool isNegative = false; 20 | bool firstDigitFound = false; 21 | bool charFlag = false; 22 | 23 | int answer = 0; 24 | 25 | for(char c : s) 26 | { 27 | if(!firstDigitFound) 28 | { 29 | if(c == ' '){ 30 | if(charFlag) return 0; 31 | continue; 32 | } 33 | if(c == '0') { 34 | charFlag = true; 35 | continue; 36 | } 37 | 38 | 39 | if(c == '-') { 40 | charFlag = true; 41 | if(isNegative) return 0; 42 | else { 43 | isNegative = true; 44 | continue; 45 | } 46 | } 47 | 48 | int ascii = (int)c; 49 | 50 | if(ascii >= 48 && ascii <= 57) { 51 | charFlag = true; 52 | firstDigitFound = true; 53 | answer = ascii - 48; 54 | } 55 | else { 56 | return 0; 57 | } 58 | } 59 | else 60 | { 61 | int ascii = (int)c; 62 | 63 | if(ascii >= 48 && ascii <= 57) { 64 | if(safeToIncrease(answer, ascii, isNegative)) { 65 | answer = (answer * 10) + (ascii - 48); 66 | } 67 | else { 68 | return isNegative? INT_MIN : INT_MAX; 69 | } 70 | } 71 | else { 72 | return isNegative? -answer : answer; 73 | } 74 | } 75 | } 76 | return isNegative? -answer : answer; 77 | } 78 | }; -------------------------------------------------------------------------------- /MayPOTD/BurningTree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Node 5 | { 6 | public: 7 | int data; 8 | Node *left; 9 | Node *right; 10 | 11 | Node(int val) 12 | { 13 | data = val; 14 | left = right = NULL; 15 | } 16 | }; 17 | 18 | class Solution 19 | { 20 | public: 21 | int minTime(Node *root, int target) 22 | { 23 | if (!root) 24 | return 0; 25 | 26 | unordered_map parent; 27 | Node *targetNode = nullptr; 28 | buildParentMap(root, nullptr, parent, target, targetNode); 29 | 30 | unordered_set visited; 31 | queue q; 32 | q.push(targetNode); 33 | visited.insert(targetNode); 34 | 35 | int time = 0; 36 | while (!q.empty()) 37 | { 38 | int sz = q.size(); 39 | bool spread = false; 40 | 41 | for (int i = 0; i < sz; ++i) 42 | { 43 | Node *cur = q.front(); 44 | q.pop(); 45 | 46 | if (cur->left && !visited.count(cur->left)) 47 | { 48 | visited.insert(cur->left); 49 | q.push(cur->left); 50 | spread = true; 51 | } 52 | 53 | if (cur->right && !visited.count(cur->right)) 54 | { 55 | visited.insert(cur->right); 56 | q.push(cur->right); 57 | spread = true; 58 | } 59 | 60 | Node *par = parent[cur]; 61 | if (par && !visited.count(par)) 62 | { 63 | visited.insert(par); 64 | q.push(par); 65 | spread = true; 66 | } 67 | } 68 | 69 | if (spread) 70 | ++time; 71 | } 72 | 73 | return time; 74 | } 75 | 76 | private: 77 | void buildParentMap(Node *node, Node *par, 78 | unordered_map &parent, 79 | int target, Node *&targetNode) 80 | { 81 | if (!node) 82 | return; 83 | parent[node] = par; 84 | if (node->data == target) 85 | { 86 | targetNode = node; 87 | } 88 | buildParentMap(node->left, node, parent, target, targetNode); 89 | buildParentMap(node->right, node, parent, target, targetNode); 90 | } 91 | }; -------------------------------------------------------------------------------- /MinWeightCycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution 5 | { 6 | public: 7 | const int INF = numeric_limits::max(); 8 | 9 | int dijkstra(int V, int src, int dest, unordered_map>> &graph) 10 | { 11 | vector dist(V, INF); 12 | priority_queue, vector>, greater>> pq; 13 | dist[src] = 0; 14 | pq.push(make_pair(0, src)); 15 | 16 | while (!pq.empty()) 17 | { 18 | pair top = pq.top(); 19 | pq.pop(); 20 | int d = top.first; 21 | int u = top.second; 22 | if (u == dest) 23 | return d; 24 | if (d > dist[u]) 25 | continue; 26 | vector> &neighbors = graph[u]; 27 | for (size_t i = 0; i < neighbors.size(); ++i) 28 | { 29 | int v = neighbors[i].first; 30 | int w = neighbors[i].second; 31 | if (dist[u] + w < dist[v]) 32 | { 33 | dist[v] = dist[u] + w; 34 | pq.push(make_pair(dist[v], v)); 35 | } 36 | } 37 | } 38 | return INF; 39 | } 40 | 41 | int findMinCycle(int V, vector> &edges) 42 | { 43 | unordered_map>> graph; 44 | for (size_t i = 0; i < edges.size(); ++i) 45 | { 46 | int u = edges[i][0], v = edges[i][1], w = edges[i][2]; 47 | graph[u].push_back(make_pair(v, w)); 48 | graph[v].push_back(make_pair(u, w)); 49 | } 50 | 51 | int minCycle = INF; 52 | 53 | for (size_t i = 0; i < edges.size(); ++i) 54 | { 55 | int u = edges[i][0], v = edges[i][1], w = edges[i][2]; 56 | 57 | vector> &adjU = graph[u]; 58 | vector> &adjV = graph[v]; 59 | adjU.erase(remove_if(adjU.begin(), adjU.end(), 60 | [v, w](const pair &p) 61 | { return p.first == v && p.second == w; }), 62 | adjU.end()); 63 | adjV.erase(remove_if(adjV.begin(), adjV.end(), 64 | [u, w](const pair &p) 65 | { return p.first == u && p.second == w; }), 66 | adjV.end()); 67 | 68 | int pathWeight = dijkstra(V, u, v, graph); 69 | if (pathWeight != INF) 70 | { 71 | minCycle = min(minCycle, pathWeight + w); 72 | } 73 | 74 | graph[u].push_back(make_pair(v, w)); 75 | graph[v].push_back(make_pair(u, w)); 76 | } 77 | 78 | return (minCycle == INF ? -1 : minCycle); 79 | } 80 | }; 81 | // damn -------------------------------------------------------------------------------- /ConnectHouses.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | // i'll use it for cycle detection in kruskal's algorithm 7 | class DisjointSetUnion 8 | { 9 | private: 10 | vector parent; 11 | 12 | public: 13 | DisjointSetUnion(int V) 14 | { 15 | parent.resize(V); 16 | for (int i = 0; i < V; ++i) 17 | { 18 | parent[i] = i; 19 | } 20 | } 21 | 22 | int find(int node) 23 | { 24 | 25 | while (parent[node] != node) 26 | { 27 | node = parent[node]; 28 | } 29 | 30 | return node; 31 | } 32 | 33 | void doUnion(int x, int y) 34 | { 35 | int parent1 = find(x); 36 | int parent2 = find(y); 37 | 38 | if (parent1 != parent2) 39 | { 40 | parent[parent1] = parent2; 41 | } 42 | } 43 | }; 44 | 45 | class Solution 46 | { 47 | public: 48 | int minCost(vector> &houses) 49 | { 50 | // code here 51 | int n = houses.size(); 52 | 53 | vector> matrix(n, vector(n)); 54 | 55 | // building the adj matrix for the weight representation 56 | for (int i = 0; i < n; ++i) 57 | { 58 | int xi = houses[i][0]; 59 | int yi = houses[i][1]; 60 | 61 | for (int j = i + 1; j < n; ++j) 62 | { 63 | 64 | int xj = houses[j][0]; 65 | int yj = houses[j][1]; 66 | 67 | int manhattanDistance = abs(xi - xj) + abs(yi - yj); 68 | matrix[i][j] = manhattanDistance; 69 | matrix[j][i] = manhattanDistance; 70 | } 71 | } 72 | 73 | // a heap of triplets (weight, u, v) for kruskal 74 | priority_queue, vector>, greater>> minHeap; // okay this is long 75 | 76 | // load the edges 77 | for(int i = 0; i < n; ++i) { 78 | for(int j = i+1; j < n; ++j) { 79 | minHeap.push({matrix[i][j], i, j}); 80 | } 81 | } 82 | 83 | // union find to track if a cycle is created 84 | DisjointSetUnion dsu(n); 85 | 86 | int processedEdges = 0; 87 | int totalCost = 0; 88 | while(processedEdges < n-1) { 89 | 90 | // gfg doesnt support stuctured bindings oof 91 | tuple edge = minHeap.top(); 92 | minHeap.pop(); 93 | 94 | int weight = get<0>(edge); 95 | int u = get<1>(edge); 96 | int v = get<2>(edge); 97 | 98 | if(dsu.find(u) != dsu.find(v)) { 99 | totalCost += weight; 100 | dsu.doUnion(u,v); 101 | ++processedEdges; 102 | } 103 | } 104 | 105 | 106 | return totalCost; 107 | } 108 | }; 109 | 110 | int main() 111 | { 112 | Solution sol; 113 | vector> houses = {{0,0}, {1,1}, {1, 3}, {3, 0}}; 114 | 115 | cout << sol.minCost(houses); 116 | } -------------------------------------------------------------------------------- /AlienDictionary.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution 5 | { 6 | private: 7 | bool dfs(char node, unordered_map> &graph, unordered_map &visited, string &res) 8 | { 9 | if (visited[node] == 1) 10 | return false; 11 | if (visited[node] == 2) 12 | return true; 13 | 14 | visited[node] = 1; 15 | 16 | if (graph.count(node)) { 17 | for (char neighbor : graph[node]) 18 | { 19 | if (!dfs(neighbor, graph, visited, res)) 20 | return false; 21 | } 22 | } 23 | 24 | visited[node] = 2; 25 | res += node; 26 | return true; 27 | } 28 | 29 | public: 30 | string findOrder(vector &words) 31 | { 32 | int n = words.size(); 33 | unordered_set chars; 34 | for (const string& word : words) 35 | { 36 | for (char letter : word) 37 | { 38 | chars.insert(letter); 39 | } 40 | } 41 | 42 | unordered_map> graph; 43 | for(char c : chars) { 44 | graph[c] = {}; 45 | } 46 | 47 | for (int i = 0; i < n - 1; ++i) 48 | { 49 | string word1 = words[i]; 50 | string word2 = words[i + 1]; 51 | int len1 = word1.size(); 52 | int len2 = word2.size(); 53 | int minLen = min(len1, len2); 54 | bool foundDifference = false; 55 | 56 | for (int j = 0; j < minLen; ++j) 57 | { 58 | char u = word1[j]; 59 | char v = word2[j]; 60 | if (u != v) 61 | { 62 | bool edgeExists = false; 63 | if (graph.count(u)) { 64 | for(char neighbor : graph[u]) { 65 | if (neighbor == v) { 66 | edgeExists = true; 67 | break; 68 | } 69 | } 70 | } 71 | if (!edgeExists) { 72 | graph[u].push_back(v); 73 | } 74 | foundDifference = true; 75 | break; 76 | } 77 | } 78 | 79 | if (!foundDifference && len1 > len2) 80 | { 81 | return ""; 82 | } 83 | } 84 | 85 | string res; 86 | unordered_map visited; 87 | for (char c : chars) 88 | { 89 | visited[c] = 0; 90 | } 91 | 92 | vector charList(chars.begin(), chars.end()); 93 | sort(charList.begin(), charList.end()); 94 | 95 | for (char c : charList) 96 | { 97 | if (visited[c] == 0) 98 | { 99 | if (!dfs(c, graph, visited, res)) 100 | { 101 | return ""; 102 | } 103 | } 104 | } 105 | 106 | reverse(res.begin(), res.end()); 107 | return res; 108 | } 109 | }; 110 | // this was tough.. -------------------------------------------------------------------------------- /160/day15.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution { 5 | public: 6 | string addBinary(string& s1, string& s2) { 7 | // your code here 8 | string answer; 9 | answer.reserve(1e6 + 2); 10 | 11 | int l1 = s1.size() - 1; 12 | int l2 = s2.size() - 1; 13 | 14 | bool carryFlag = false; 15 | 16 | while(l1 >= 0 && l2 >= 0) 17 | { 18 | 19 | if(s1[l1] == '0' && s2[l2] == '0') 20 | { 21 | if(carryFlag){ 22 | answer.push_back('1'); 23 | } 24 | else { 25 | answer.push_back('0'); 26 | } 27 | carryFlag = false; 28 | } 29 | else if((s1[l1] == '0' && s2[l2] == '1') || (s1[l1] == '1' && s2[l2] == '0')) 30 | { 31 | if(carryFlag) 32 | { 33 | answer.push_back('0'); 34 | carryFlag = true; 35 | } 36 | else { 37 | answer.push_back('1'); 38 | carryFlag = false; 39 | } 40 | } 41 | else 42 | { 43 | if(carryFlag) 44 | { 45 | answer.push_back('1'); 46 | } 47 | else { 48 | answer.push_back('0'); 49 | } 50 | carryFlag = true; 51 | } 52 | 53 | --l1; 54 | --l2; 55 | } 56 | 57 | 58 | 59 | while(l1 >= 0) 60 | { 61 | if(carryFlag) 62 | { 63 | if(s1[l1] == '1') { 64 | answer.push_back('0'); 65 | carryFlag = true; 66 | } 67 | else { 68 | answer.push_back('1'); 69 | carryFlag = false; 70 | } 71 | } 72 | else { 73 | answer.push_back(s1[l1]); 74 | } 75 | l1--; 76 | } 77 | 78 | while(l2 >= 0) 79 | { 80 | if(carryFlag) 81 | { 82 | if(s2[l2] == '1') { 83 | answer.push_back('0'); 84 | carryFlag = true; 85 | } 86 | else { 87 | answer.push_back('1'); 88 | carryFlag = false; 89 | } 90 | } 91 | else { 92 | answer.push_back(s2[l2]); 93 | } 94 | l2--; 95 | } 96 | if(carryFlag) answer.push_back('1'); 97 | 98 | int temp = answer.size() - 1; 99 | while(temp > 0 && answer[temp] == '0') { 100 | answer.pop_back(); 101 | temp--; 102 | } 103 | 104 | reverse(answer); 105 | return answer; 106 | 107 | } 108 | private: 109 | void reverse(string &answer) 110 | { 111 | int left = 0; 112 | int right = answer.size() - 1; 113 | while(left < right) 114 | { 115 | std::swap(answer[left++], answer[right--]); 116 | } 117 | } 118 | }; -------------------------------------------------------------------------------- /RottenOranges.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | 6 | class Solution { 7 | public: 8 | int UNOPTIMIZEDorangesRotting(vector>& mat) { 9 | 10 | int n = mat.size(); 11 | int m = mat[0].size(); 12 | 13 | // Code here 14 | int gen = 0; 15 | bool infected = false; 16 | 17 | vector> genMap(n, vector(m, -1)); 18 | 19 | 20 | 21 | while(true) { 22 | infected = false; 23 | 24 | for(int i = 0; i < n; ++i) { 25 | 26 | for(int j = 0; j < m; ++j) { 27 | 28 | if(mat[i][j] != 2) continue; 29 | 30 | if(genMap[i][j] == gen) continue; 31 | // cout << "test "; 32 | 33 | // top 34 | if(i > 0 && mat[i-1][j] == 1) { 35 | mat[i-1][j] = 2; 36 | infected = true; 37 | genMap[i-1][j] = gen; 38 | } 39 | 40 | // down 41 | if(i < n-1 && mat[i+1][j] == 1) { 42 | mat[i+1][j] = 2; 43 | infected = true; 44 | genMap[i+1][j] = gen; 45 | } 46 | 47 | // left 48 | if(j > 0 && mat[i][j-1] == 1) { 49 | mat[i][j-1] = 2; 50 | infected = true; 51 | genMap[i][j-1] = gen; 52 | } 53 | 54 | // right 55 | if(j < m-1 && mat[i][j+1] == 1) { 56 | mat[i][j+1] = 2; 57 | infected = true; 58 | genMap[i][j+1] = gen; 59 | } 60 | 61 | } 62 | 63 | } 64 | 65 | 66 | if(!infected) break; 67 | gen++; 68 | } 69 | 70 | int freshCount = 0; 71 | 72 | for(int i = 0; i < n; ++i) { 73 | for(int j = 0; j < m; ++j) { 74 | if(mat[i][j] == 1) ++freshCount; 75 | } 76 | } 77 | 78 | if(freshCount) { 79 | // cout << gen; 80 | return -1; 81 | } 82 | else { 83 | return gen; 84 | } 85 | } 86 | // this wasn't accepted cause of the O(m*n*gen) time complexity, i guess i'll have to do better. 87 | 88 | int orangesRotting(vector>& grid) { 89 | // Code here 90 | int n = grid.size(); 91 | int m = grid[0].size(); 92 | 93 | queue> q; 94 | 95 | int freshOranges = 0; 96 | int minutes = 0; 97 | 98 | // adding all rotten oranges to queue and counting the fresh oranges 99 | for(int i = 0; i < n; ++i) { 100 | for(int j = 0; j < m; ++j) { 101 | if(grid[i][j] == 1){ 102 | ++freshOranges; 103 | } 104 | else if(grid[i][j] == 2) { 105 | q.push({i, j}); 106 | } 107 | } 108 | } 109 | // if there aren't any fresh oranges , all oranges are already rotten hence output = 0; 110 | if(!freshOranges) return 0; 111 | 112 | // bfs time 113 | vector> directions = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}}; 114 | while(!q.empty()) { 115 | int size = q.size(); 116 | bool infected = false; 117 | 118 | // process the rotten oranges present in the queue 119 | for(int i = 0; i < size; ++i) { 120 | 121 | pair front = q.front(); 122 | int x = front.first; 123 | int y = front.second; 124 | q.pop(); 125 | 126 | // infect the neighbors 127 | for(auto p : directions) { 128 | 129 | int nx = x + p.first; 130 | int ny = y + p.second; 131 | 132 | if(nx >= 0 && nx < n && ny >= 0 && ny < m && grid[nx][ny] == 1) { 133 | grid[nx][ny] = 2; // infected 134 | q.push({nx, ny}); // push to infected queue 135 | freshOranges--; 136 | infected = true; 137 | } 138 | } 139 | } 140 | 141 | // if there has been an infection in the last iteration of queue. 142 | if(infected) ++minutes; 143 | } 144 | 145 | 146 | if(freshOranges == 0) { 147 | // every orange was successfully infected . you win 148 | return minutes; 149 | } 150 | else { 151 | // a fresh orange survived... 152 | return -1; 153 | } 154 | } 155 | 156 | // Time Complexity - O(n*m) 157 | // Space Complexity = O(n*m) 158 | 159 | }; --------------------------------------------------------------------------------