├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── Striver CP Sheet
└── Readme.md
└── Striver SDE Sheet
├── Day - 1 (Arrays)
├── Dutch Flag Algorithm.cpp
├── Find duplicate in array.cpp
├── Kadane Algorithm.cpp
├── Merge 2 Sorted Arr (No Extra Space). cpp
├── Merge Overlapping SubIntervals.cpp
└── Repeat And Missing Number.cpp
├── Day - 10 (Recursion&Backtracking)
├── M Colouring Problem.cpp
├── N Queens Problem.cpp
├── Permutation in String.cpp
├── Rat in a Maze.cpp
└── Sudoku.cpp
├── Day - 11 (Binary Search)
├── Kth Element Of Two Sorted Arrays.cpp
├── Matrix Median.cpp
├── Median of 2 sorted arrays(Hard).cpp
├── Search element in sorted rotated array.cpp
├── Single Element in Sorted Array.cpp
└── Sqrt(x).cpp
├── Day - 12 (Bits)
├── Count Total Set Bits.cpp
├── Counting Bits.cpp
├── Most Significant Bit.cpp
├── Power of 2.cpp
└── Subsets.cpp
├── Day - 13 (Stacks and Queues)
├── BFS.cpp
├── Balanced Parenthesis.cpp
├── Implement Queue using Stack.cpp
├── Implement Stack using Queue.cpp
└── Next Greater Element.cpp
├── Day - 14
├── Implement Min Stack.cpp
├── LRU Cache (Hard)(VVIP).cpp
├── Largest Rectangle In A Histogram.cpp
├── Next Smaller Element.cpp
├── Rotten Oranges.cpp
└── Sliding Window Maximum.cpp
├── Day - 15 (Strings)
├── Implement ATOI and STRSTR.cpp
├── Longest Common Prefix.cpp
├── Longest Palindrome substring.cpp
├── Reverse words in String.cpp
└── Roman No. to Integer and vice versa.cpp
├── Day - 16 (Strings)
├── Check for anagrams.cpp
├── Compare Version Numbers.cpp
└── Count and Say.cpp
├── Day - 17 (Binary Tree)
├── Bottom View Of Binary Tree.cpp
├── Inorder Iterative.cpp
├── Inorder Recursive.cpp
├── Inorder Traversal(both).cpp
├── Left View Of Binary Tree.cpp
├── Postorder (both).cpp
├── Postorder Iterative.cpp
├── Postorder Recursive.cpp
├── Preorder (both).cpp
├── Preorder Iterative.cpp
├── Preorder Recursive.cpp
├── Right View of Binary Tree.cpp
└── Top View Of Binary Tree.cpp
├── Day - 18 (Binary Tree)
├── Check if trees identical.cpp
├── Diameter of tree.cpp
├── Height balanced Check.cpp
├── Height of Binary Tree.cpp
├── LCA in Binary Tree.cpp
├── Level Order Traversal.cpp
└── Level order in Spiral.cpp
├── Day - 19 (Binary Tree)
├── Construct BTree from Inorder and Postorder.cpp
├── Construct BTree from Inorder and Preorder(Hard).cpp
├── Flatten BTree to LinkedList.cpp
├── Maximum Path Sum(Hard).cpp
└── Symmetric Tree(Mirror of itself).cpp
├── Day - 2 (Arrays)
├── Best Time to Buy and Sell Stock - 1.cpp
├── Inversion Count.cpp
├── Next Permutation.cpp
├── Pascal Triangle. cpp
├── Rotate Matrix.cpp
└── Set Matrix Zeros. cpp
├── Day - 20 (BST)
├── Check if BT is BST.cpp
├── Construct BST from given keys.cpp
├── Inorder predecessor and succ in BST.cpp
├── LCA of BST.cpp
├── Populate next right pointers.cpp
└── Search in BST.cpp
├── Day - 21 (BST)
├── BST Iterator.cpp
├── Find pair with sum in BST.cpp
├── Floor and ceil of BST.cpp
├── K-th largest element in BST.cpp
├── K-th smallest in BST.cpp
├── Max sum BST in BT(Hard).cpp
└── Serialize and Deserialize(Hard).cpp
├── Day - 23 (Graphs)
├── BFS.cpp
├── Bipartite Check(BFS).cpp
├── Bipartite Check(DFS).cpp
├── Clone a Graph (DFS)(Hard).cpp
├── Cycle Detection Directed Graph (BFS)(Kahn).cpp
├── Cycle Detection Directed Graph(DFS).cpp
├── Cycle Detection Undirected Graph(BFS)(Hard).cpp
├── Cycle Detection Undirected Graph(DFS).cpp
├── DFS.cpp
├── Topological Sort (BFS)(Kahn).cpp
└── Topological Sort(DFS).cpp
├── Day - 24 (Graphs)
├── Articulation Point (VHard).cpp
├── Bellman Ford's Algo.cpp
├── Bridges in Graph (VHard).cpp
├── Dijkstra's Algo.cpp
├── Disjoint Set(Union by rank and Path Compression).cpp
├── Floyd Warshall Algo.cpp
├── Kruskal's Algo(Hard).cpp
├── Prim's Algo.cpp
├── Shortest Path DAG(Hard).cpp
├── Shortest Path Undirected Graph.cpp
└── Strongly Connected Components (Kosaraju).cpp
├── Day - 25 (DP)
├── 0-1 Knapsack (all methods).cpp
├── Edit Distance.cpp
├── Longest Common Subsequence.cpp
├── Longest Inc Subsequence.cpp
├── Matrix Chain Multiplication(Hard).cpp
├── Max Sum Inc Subsequence (MSIS).cpp
└── Maximum Product Subarray.cpp
├── Day - 26 (DP)
├── Climbing Stairs.cpp
├── Coin Change (2 methods).cpp
├── Egg Dropping(Hard).cpp
├── Max Profit Job scheduling(Hard).cpp
├── Max Sum Path in Matrix(2 methods).cpp
├── Rod Cutting.cpp
├── Subset Sum.cpp
└── Word Break.cpp
├── Day - 3 (Arrays&Math)
├── Majority Element - 2.cpp
├── Majority Element.cpp
├── Search 2-D Matrix.cpp
├── Unique Paths.cpp
└── pow(X,n).cpp
├── Day - 4 (Hashing)
├── 2 Sum.cpp
├── 4 Sum.cpp
├── Largest Subarray with 0 sum.cpp
└── Longest Consecutive Sequence.cpp
├── Day - 5 (Linked List)
├── Add 2 Linked List Numbers.cpp
├── Delete Node In A Linked List.cpp
├── Merge Two Sorted Lists.cpp
├── Middle Of Linked List.cpp
├── Remove Nth Node from End of List.cpp
└── Reverse Linked List.cpp
├── Day - 6 (Linked List)
├── Find The Starting Point Of Loop.cpp
├── Intersection of 2 LinkedLists.cpp
├── Linked List Cycle.cpp
├── Palindrome Linked List.cpp
└── Reverse Nodes In K Group.cpp
├── Day - 7 (2 pointer)
├── 3 Sum.cpp
├── Clone A Linked List With Random And Next Pointer.cpp
├── Max Consecutive Ones.cpp
├── Remove Duplicates from Sorted Array.cpp
└── Trapping Rain Water.cpp
├── Day - 8 (Greedy)
├── Coin Change.cpp
├── Fractional Knapsack.cpp
├── Job Sequencing Problem.cpp
├── Minimum Platforms.cpp
└── N meetings in one room.cpp
└── Day - 9 (Recursion)
├── Combination Sum-1.cpp
├── Combination Sum-2.cpp
├── Palindrome Partitioning.cpp
├── Permutation Sequence.cpp
├── Subset Sums.cpp
└── Subset-2.cpp
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # RULES OF CONTRIBUTING
2 |
3 | - Within 100 Days of Leetcode folder, add folders for each day. Format : Day - X
4 | - For each sum you do, write the fullname of the question fully. e.g. Fractional Knapsack.cpp. Name **MUST** match the exact question name in Leetcode.
5 | - Add all the programs you **All** did that day within that day's folder i.e. everyone shares the same day folder.
6 | - Make sure there is **NO** repetition of questions whatsoever. Check the repo before solving a question
7 | - If you are providing a better way to solve an already present question, make a comment below existing code e.g. # Method-2 and then paste your code below comment
8 | - Before submission,make sure the code works on whatever platform you ran it in e.g.Leetcode, or GFG
9 | - If you can add small comments in the code to explain your thought process, that would help you when revising.
10 | - **No spam codes/incomplete codes will be allowed**
11 |
12 | > 100 Days of Leetcode -> Create folder "Day - x" (same format) -> All contributors add the Leetcode questions they did on that day. No overlaps. If 2 people solved the same qn, one of you can decide to commit and the other one should not (unless it is a different method. See point 5)
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 HariHaran
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Striver SDE Sheet Solutions (C++)
3 |
4 |
5 |
6 | &font=Source%20Code%20Pro&forks=1&issues=1&language=1&owner=1&pattern=Circuit%20Board&pulls=1&stargazers=1&theme=Dark)
7 |
8 |
9 | This is everything you need to ace your coding interviews! ✨
10 |
11 | ## 🎯 Purpose
12 | After the huge success of my [**Javascript A-Z Notes repository**](https://github.com/HariAcidReign/JavaScript-A-Z-Notes), I had been toying with the idea to make a repo for all the questions in the SDE Sheet. This might be of massive help especially if you are preparing for placements and want a quick revision of the problems before your OA or interviews 🔥 (Almost) All the questions have 2 ways of solving (mine and my friend's) + **every answer has detailed comments for every step**
13 |
14 | I myself used the **SDE Sheet** extensively and was able to bag an offer for 6 months (Jan-Jun) internship at **Amazon** and became one of the 8 people to get selected for this on-campus opportunity from over a 1000 candidates!🥳 So, here is my way of saying *thank you!* to takeUforward and the TUF fam 🤎
15 |
16 | ## 🥂 Who created this?
17 | This is a painstaking effort of both **mine** and my very good friend + coding buddy [**Siddharth**](https://github.com/DiligentCoder-20022001). Go checkout our other awesome repos!
18 |
19 | ## 💗 Contributions
20 | I'll always work on my DSA skills, so expect this repo to get updated constantly.
21 | - Time and space complexities haven't been added for some questions, so if you want to start your open-source journey from here, you are most welcome to!
22 | - Also, if you have a better (and tested) implementation for any problem, feel free to add. I review PRs frequently 🤓
23 |
24 | ## 📝 Resource Used
25 | - [TakeUForward channel on Youtube ](https://www.youtube.com/channel/UCJskGeByzRRSvmOyZOz61ig)
26 | - [SDE Sheet](https://docs.google.com/document/d/1SM92efk8oDl8nyVw8NHPnbGexTS9W-1gmTEYfEurLWQ/edit?usp=sharing)
27 |
--------------------------------------------------------------------------------
/Striver CP Sheet/Readme.md:
--------------------------------------------------------------------------------
1 | Here is where I will be solving the CP Sheet created by Striver to improve myself in Competitive Programming
2 |
3 |
4 | Link: https://docs.google.com/document/d/1vShwt8yXYUOgkF53-iYAuJXWR7Yi5VSJrW2xB49o0PM/edit
5 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 1 (Arrays)/Dutch Flag Algorithm.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 | // https://leetcode.com/problems/sort-colors/
3 |
4 | class Solution
5 | {
6 | public:
7 | void sortColors(vector &A)
8 | {
9 | int low = 0, mid = 0;
10 | int hi = A.size() - 1;
11 |
12 | while (mid <= hi)
13 | {
14 | if (A[mid] == 0)
15 | swap(A[mid++], A[low++]);
16 | else if (A[mid] == 1)
17 | mid++;
18 | else
19 | {
20 | // if it is 2
21 | swap(A[mid], A[hi--]); // no increment of mid. Only hi decrement as we have included mid condt in 0 and 1 case, and sometimes we get a 0 after swapping
22 | // with hi which might not get swapped with low if we incremented mid here also.
23 | }
24 | }
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 1 (Arrays)/Find duplicate in array.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | int findDuplicate(vector& nums) {
4 | int fast = nums[0], slow = nums[0];
5 |
6 | // use do while to run first time even when fast = slow. while will simply break @ start
7 | // and do while will run any code min 1 time irrespective of condition
8 | do {
9 | fast = nums[nums[fast]];
10 | slow = nums[slow];
11 | } while (slow != fast);
12 |
13 | // fast will stay at meeting point and slow comes back to start
14 | slow = nums[0];
15 |
16 | while(fast != slow){
17 | slow = nums[slow];
18 | fast = nums[fast];
19 | }
20 | return slow; // return fast;
21 | }
22 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 1 (Arrays)/Kadane Algorithm.cpp:
--------------------------------------------------------------------------------
1 | // Find max contiguous subarray
2 |
3 | int maxSubArray(vector &nums)
4 | {
5 | int max_so_far = INT_MIN, max_ending_here = 0;
6 |
7 | for (int i = 0; i < nums.size(); i++)
8 | {
9 | max_ending_here += nums[i];
10 | if (max_so_far < max_ending_here)
11 | max_so_far = max_ending_here;
12 | if (max_ending_here < 0)
13 | max_ending_here = 0; // to get only +ve ans
14 | }
15 | return max_so_far;
16 | }
17 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 1 (Arrays)/Merge 2 Sorted Arr (No Extra Space). cpp:
--------------------------------------------------------------------------------
1 | int nextGap(int x)
2 | {
3 | if(x <= 1)
4 | return 0;
5 | else
6 | return (x/2) + (x%2);
7 | }
8 | void merge(int arr1[], int arr2[], int n, int m) {
9 | // code here
10 | int i, j;
11 | int sum = m+ n;
12 | int gap = nextGap(sum);
13 | while(gap > 0)
14 | {
15 | //first array -> arr1
16 | for(i = 0; i + gap < n; i++)
17 | {
18 | if(arr1[i] > arr1[i+gap])
19 | swap(arr1[i], arr1[i+gap]);
20 | }
21 | //for both the first and second array
22 | if(gap > n)
23 | j = gap - n;
24 | else
25 | j = 0;
26 | for(; j < m && i < n; j++, i++)
27 | {
28 | if(arr1[i] > arr2[j])
29 | swap(arr1[i], arr2[j]);
30 | }
31 | //for the second array only
32 | if(j < m)
33 | {
34 | for(j = 0; j + gap < m; j++)
35 | {
36 | if(arr2[j] > arr2[j+gap])
37 | swap(arr2[j], arr2[j+gap]);
38 | }
39 | }
40 | gap = nextGap(gap);
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 1 (Arrays)/Merge Overlapping SubIntervals.cpp:
--------------------------------------------------------------------------------
1 | class Solution
2 | {
3 | public:
4 | vector> merge(vector> &intervals)
5 | {
6 | //OM GAN GANAPATHAYE NAMO NAMAH
7 | //JAI SHRI RAM
8 | //JAI BAJRANGBALI
9 | //AMME NARAYANA, DEVI NARAYANA, LAKSHMI NARAYANA, BHADRE NARAYANA
10 | int p1 = 0, p2 = 0;
11 | int n = intervals.size();
12 | vector> inter;
13 | for (int i = 0; i < n; i++)
14 | {
15 | inter.push_back(make_pair(intervals[i][0], intervals[i][1]));
16 | }
17 | sort(inter.begin(), inter.end());
18 | int k = 0;
19 | while (p1 < n && p2 < n)
20 | {
21 | inter[k].first = inter[p2].first;
22 | inter[k].second = inter[p2].second;
23 | while (p1 < n && inter[k].second >= inter[p1].first)
24 | {
25 | inter[k].first = min(inter[k].first, inter[p1].first);
26 | inter[k].second = max(inter[k].second, inter[p1].second);
27 | p1++;
28 | }
29 | k++;
30 | p2 = p1;
31 | }
32 | vector> res;
33 | for (int i = 0; i < k; i++)
34 | {
35 | vector temp;
36 | temp.push_back(inter[i].first);
37 | temp.push_back(inter[i].second);
38 | res.push_back(temp);
39 | }
40 | return res;
41 | }
42 | };
43 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 1 (Arrays)/Repeat And Missing Number.cpp:
--------------------------------------------------------------------------------
1 | int *findTwoElement(int *arr, int n)
2 | {
3 | // code here
4 | int xor1 = 0;
5 | for (int i = 0; i < n; i++)
6 | xor1 = xor1 ^ arr[i];
7 | for (int i = 1; i <= n; i++)
8 | xor1 = xor1 ^ i;
9 | //{1,3,3} and {1,2,3}
10 | //2^3 => 5
11 | //repeating -> first arrayb
12 | //missing array -> second array
13 | //x & ~(x-1)
14 | int setBit = xor1 & (~(xor1 - 1));
15 | int x = 0, y = 0;
16 | //first array
17 | for (int i = 0; i < n; i++)
18 | {
19 | if (arr[i] & setBit)
20 | {
21 | x = x ^ arr[i];
22 | }
23 | else
24 | {
25 | y = y ^ arr[i];
26 | }
27 | }
28 | //second array
29 | for (int i = 1; i <= n; i++)
30 | {
31 | if (i & setBit)
32 | {
33 | x = x ^ i;
34 | }
35 | else
36 | {
37 | y = y ^ i;
38 | }
39 | }
40 | int *res;
41 | //we ll search for x or y in the first array
42 | int flagx = 0;
43 | int flagy = 0;
44 | for (int i = 0; i < n; i++)
45 | {
46 | if (arr[i] == x)
47 | {
48 | flagx = 1;
49 | break;
50 | }
51 | else if (arr[i] == y)
52 | {
53 | flagy = 1;
54 | break;
55 | }
56 | }
57 | if (flagx == 1)
58 | {
59 | res[0] = x;
60 | res[1] = y;
61 | return res;
62 | }
63 | else
64 | {
65 | res[0] = y;
66 | res[1] = x;
67 | return res;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 10 (Recursion&Backtracking)/Permutation in String.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | bool checkInclusion(string s1, string s2) {
4 | // make 2 hashmaps for both strings
5 | vector hash1(26,0);
6 | vector hash2(26,0);
7 | int N1 = s1.size();
8 | int N2 = s2.size();
9 | // we have to see if s2 contains permutation of s1
10 | if(N2 < N1) return false;
11 |
12 |
13 | // first we fill up hash counts in both
14 | int left = 0, right = 0;
15 | while(right < N1){
16 | hash1[s1[right] - 'a']++;
17 | hash2[s2[right] - 'a']++;
18 | right++;
19 | }
20 | right--; // point to end of first window
21 |
22 | while(right < N2){
23 | if(hash1 == hash2) return true;
24 | right++;
25 | if(right != N2){
26 | hash2[s2[right] - 'a']++;
27 | }
28 | hash2[s2[left] - 'a']--;
29 | left++;
30 | }
31 | return false;
32 | }
33 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 10 (Recursion&Backtracking)/Rat in a Maze.cpp:
--------------------------------------------------------------------------------
1 | // Hari and Sid
2 |
3 | class Solution{
4 | public:
5 | vector findPath(vector> &m, int n) {
6 | vector res;
7 | string path;
8 | vector> seen( n , vector (n, 0));
9 | helper(0,0,m,n, res, path, seen);
10 | return res;
11 | }
12 |
13 | bool isSafe(int row, int col, vector> &m, vector> &seen){
14 | if(row < 0 || row >= m.size() || col < 0 || col >= m.size() || seen[row][col] == 1 ||
15 | m[row][col] == 0) return false;
16 |
17 | return true;
18 | }
19 |
20 | void helper(int row, int col, vector> &m, int n, vector &res,
21 | string &path, vector> &seen){
22 | if(row >= n || col >= n) return; // bounding case
23 | // destination reached? (base case)
24 | if(row == n-1 && col == n-1){
25 | res.push_back(path);
26 | return;
27 | }
28 | // destination not reached
29 | if(isSafe(row, col, m, seen)){
30 | seen[row][col] = 1;
31 | if(isSafe(row+1, col, m, seen)){ // D
32 | path.push_back('D');
33 | helper(row+1, col, m, n, res, path, seen);
34 | path.pop_back();
35 | }
36 | if(isSafe(row, col-1, m, seen)){ // L
37 | path.push_back('L');
38 | helper(row, col-1, m, n, res, path, seen);
39 | path.pop_back();
40 | }
41 | if(isSafe(row, col+1, m, seen)){ // R
42 | path.push_back('R');
43 | helper(row, col+1, m, n, res, path, seen);
44 | path.pop_back();
45 | }
46 | if(isSafe(row-1, col, m, seen)){ // U
47 | path.push_back('U');
48 | helper(row-1, col, m, n, res, path, seen);
49 | path.pop_back();
50 | }
51 | seen[row][col] = 0;
52 | }
53 |
54 |
55 | }
56 | };
57 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 10 (Recursion&Backtracking)/Sudoku.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | bool isValidSudoku(vector>& board) {
6 | // this is an ad-hoc method
7 | map row[9],col[9],blk[9];
8 | char c;
9 | for(int i = 0;i<9;i++){
10 | for(int j = 0;j<9;j++){
11 | c = board[i][j];
12 | if((c!='.')&&(0> &matrix, int r, int c){
6 | //find the minimum element -> check the first column
7 | int minEle = INT_MAX;
8 | for(int i = 0; i < r; i++)
9 | {
10 | minEle = min(minEle, matrix[i][0]);
11 | }
12 | //find the maximum element
13 | int maxEle = INT_MAX;
14 | for(int i = 0; i < r; i++)
15 | {
16 | maxEle = max(maxEle, matrix[i][c-1]);
17 | }
18 | int res = -1;
19 | int dez = (r*c+1)/2;
20 | while(minEle < maxEle)
21 | {
22 | int mid = minEle + (maxEle - minEle)/2;
23 | //search the number of elements less than mid in the matrix
24 | int cnt = 0;
25 | for(int i = 0; i < r; i++)
26 | {
27 | cnt += upper_bound(matrix[i].begin(), matrix[i].end(), mid) - matrix[i].begin();
28 | }
29 | if(cnt < dez)
30 | {
31 | minEle = mid+1;
32 | }
33 | else
34 | {
35 | maxEle = mid;
36 | }
37 | }
38 | return minEle;
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 11 (Binary Search)/Median of 2 sorted arrays(Hard).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | // helpers
6 | int getMax(vector nums, int part){
7 | if(part == 0){
8 | // if partition is in front of nums then leftX should be INT_MIN and not some random garbage value
9 | return INT_MIN;
10 | }
11 | else return nums[part-1];
12 | }
13 |
14 | int getMin(vector nums, int part){
15 | // if partition goes out of bounds of nums
16 | if(part == nums.size()){
17 | return INT_MAX;
18 | }
19 | else return nums[part];
20 | }
21 |
22 |
23 | double findMedianSortedArrays(vector& nums1, vector& nums2) {
24 | // HARD COMMON INTERVIEW DnC QN
25 | // nums1 has to be the smaller of the two
26 | if(nums1.size() > nums2.size()){
27 | nums1.swap(nums2);
28 | }
29 |
30 | int low = 0, hi = nums1.size();
31 | int combinedLength = nums1.size() + nums2.size();
32 | // combinedL can either be even or odd. Flow goes based on which one it is
33 |
34 | while(low <= hi){
35 | int partX = low + (hi-low) / 2; // partition in nums1
36 | int partY = (combinedLength + 1) / 2 - (partX);
37 |
38 | // get no. directly to left of partitions (both)
39 | int leftX = getMax(nums1, partX);
40 | int leftY = getMax(nums2, partY);
41 |
42 | // get no. directly to right of partitions (both)
43 | int rightX = getMin(nums1, partX);
44 | int rightY = getMin(nums2, partY);
45 |
46 | /* 2 conditions for both arr partitions to be valid
47 | 1. no. on left of partX (nums1) <= no. on right of partY (nums2)
48 | 2. no. on left of partY (nums2) <= no. on right of partX (nums1)
49 | */
50 |
51 | // partitions valid check
52 | if(leftX <= rightY && leftY <= rightX){
53 | double res;
54 | if(combinedLength % 2 == 0){
55 | // even -> max of left partitions + min of right / 2
56 | res = (max(leftX, leftY) + min(rightX, rightY)) / 2.0;
57 | //used 2.0 for double dtype division
58 | }
59 | else {
60 | res = max(leftX, leftY); // odd->max of left sides of both partitions will give median of combined array
61 | }
62 | return res;
63 | }
64 |
65 | // if current partitions invalid
66 | if(leftX > rightY) hi = partX - 1;
67 | else if(leftY > rightX) low = partX + 1;
68 | }
69 |
70 | return -1;
71 |
72 |
73 | }
74 |
75 | };
76 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 11 (Binary Search)/Search element in sorted rotated array.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | int search(vector& nums, int target) {
4 | // rotated array will definitely have minimum ONE strictly inc. section
5 | int N = nums.size();
6 | int left = 0, right = N-1;
7 |
8 | while(left <= right){
9 | int mid = left + (right-left)/2;
10 | if(nums[mid] == target) return mid;
11 | // now we check if left part of mid strictly inc.
12 | else if(nums[mid] >= nums[left]){
13 | // check if target is in this strictly inc left part
14 | if(target >= nums[left] && target <= nums[mid]){
15 | right = mid-1;
16 | } else {
17 | //target not in strictly inc left part. So search right
18 | left = mid+1;
19 | }
20 | }
21 | // if left part not strictly inc. 100% right part is strictly inc
22 | else {
23 | if(target >= nums[mid] && target <= nums[right]){
24 | left = mid+1;
25 | }
26 | else right = mid-1;
27 | }
28 | }
29 | // if not found
30 | return -1;
31 | }
32 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 11 (Binary Search)/Single Element in Sorted Array.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | int singleNonDuplicate(vector& nums) {
4 | // Sorting, and hashing are 2 easy methods. This one is ad-hoc
5 | unordered_set s;
6 | int sum1 = 0, sum2 = 0;
7 | for(int it: nums) s.insert(it);
8 | for(int i: s) sum1+=i;
9 | sum1 *= 2;
10 | for(int j: nums) sum2 += j;
11 | int res = sum1 - sum2;
12 | return res;
13 | }
14 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 11 (Binary Search)/Sqrt(x).cpp:
--------------------------------------------------------------------------------
1 | // Sid
2 |
3 | class Solution {
4 | public:
5 | int mySqrt(int x) {
6 | if(x == 0)
7 | return 0;
8 | else if(x == 1)
9 | return 1;
10 | int l = 0 , r = x;
11 | int res = -1;
12 | while(l <= r)
13 | {
14 | int mid = (int)((l+r)/2);
15 | if(mid == x/mid)
16 | {
17 | return mid;
18 | }
19 | else if(mid < x/mid)
20 | {
21 | res = mid;
22 | l = mid + 1;
23 | }
24 | else
25 | {
26 | r = mid - 1;
27 | }
28 | }
29 | return res;
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 12 (Bits)/Count Total Set Bits.cpp:
--------------------------------------------------------------------------------
1 | class Solution{
2 | public:
3 | // n: input to count the number of set bits
4 | //Function to return sum of count of set bits in the integers from 1 to n.
5 | int countSetBits(int n)
6 | {
7 | if(n == 0)
8 | return 0;
9 | int b = (int)(log2(n));
10 | int x = pow(2,b);
11 | //for the numbers above x
12 | int part1 = b*pow(2,b-1);
13 | //for the numbers below x (including the MSB alone) recur for the remaining part
14 | int part2 = (n - x + 1);
15 | return part1+part2+countSetBits(n-x);
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 12 (Bits)/Counting Bits.cpp:
--------------------------------------------------------------------------------
1 | class Solution {
2 | public:
3 | int count(int n)
4 | {
5 | int c = 0;
6 | while(n)
7 | {
8 | n = n&(n-1);
9 | c++;
10 | }
11 | return c;
12 | }
13 | vector countBits(int num) {
14 | vector res;
15 | for(int i = 0; i <= num; i++)
16 | {
17 | res.push_back(count(i));
18 | }
19 | return res;
20 | }
21 | };
22 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 12 (Bits)/Most Significant Bit.cpp:
--------------------------------------------------------------------------------
1 |
2 | int setBitNumber(int n)
3 | {
4 |
5 | // To find the position
6 | // of the most significant
7 | // set bit
8 | int k = (int)(log2(n));
9 |
10 | // To return the the value
11 | // of the number with set
12 | // bit at k-th position
13 | return 1 << k;
14 | }
15 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 12 (Bits)/Power of 2.cpp:
--------------------------------------------------------------------------------
1 |
2 | class Solution {
3 | public:
4 | bool isPowerOfTwo(int n) {
5 | if(n <= 0)
6 | return false;
7 | int x = n-1;
8 | int res = (n&x);
9 | if(res == 0)
10 | return true;
11 | else
12 | return false;
13 | }
14 | };
15 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 12 (Bits)/Subsets.cpp:
--------------------------------------------------------------------------------
1 | class Solution {
2 | public:
3 | vector> subsets(vector& nums) {
4 | int n = nums.size();
5 | int x = pow(2,n);
6 | vector> res;
7 | for(int i = 0; i < x; i++)
8 | {
9 | vector temp;
10 | for(int j = 0; j < n; j++)
11 | {
12 | if(i&(1<> levelOrder(TreeNode* root) {
6 | vector> res;
7 | if(!root) return res;
8 |
9 | queue q;
10 | q.push(root);
11 | q.push(NULL); // a NULL denotes the end of a particular level. Next level of BFS starts after a NULL
12 |
13 | vector ans;
14 | while(!q.empty()){
15 | TreeNode* curr = q.front(); q.pop();
16 | if(curr == NULL){ // current level over
17 | res.emplace_back(ans); //push particular lvl vector to ans
18 | ans.resize(0); // same as ans.clear()
19 | if(q.size() > 0) q.push(NULL); // if next lvl elements are there add a NULL behind them
20 | }
21 | else {
22 | ans.emplace_back(curr->val); // emplace_back is a faster alternative to push_back
23 | if(curr->left) q.push(curr->left);
24 | if(curr->right) q.push(curr->right);
25 | }
26 | }
27 |
28 | return res;
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 13 (Stacks and Queues)/Balanced Parenthesis.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | bool isValid(string s) {
4 | if(s.size() % 2 != 0) return false;
5 | stack stk;
6 | for(auto it: s){
7 | if(it == '(' || it == '{' || it == '[') stk.push(it);
8 | else if(it == ')' && !stk.empty() && stk.top() == '(') stk.pop();
9 | else if(it == '}' && !stk.empty() && stk.top() == '{') stk.pop();
10 | else if(it == ']' && !stk.empty() && stk.top() == '[') stk.pop();
11 | else return false;
12 | }
13 |
14 | return stk.empty();
15 | }
16 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 13 (Stacks and Queues)/Implement Queue using Stack.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class MyQueue {
4 | public:
5 | /** Initialize your data structure here. */
6 | stack s1, s2;
7 | MyQueue() {
8 |
9 | }
10 |
11 | /** Push element x to the back of queue. */
12 | void push(int x) {
13 | s1.push(x);
14 | }
15 |
16 | /** Removes the element from in front of queue and returns that element. */
17 | int pop() {
18 | while(s1.size()){
19 | s2.push(s1.top());
20 | s1.pop();
21 | }
22 | int temp = s2.top(); s2.pop();
23 | while(s2.size()){
24 | s1.push(s2.top()); s2.pop();
25 | }
26 | return temp;
27 | }
28 |
29 | /** Get the front element. */
30 | int peek() {
31 | while(s1.size()){
32 | s2.push(s1.top());
33 | s1.pop();
34 | }
35 | int temp = s2.top();
36 | while(s2.size()){
37 | s1.push(s2.top()); s2.pop();
38 | }
39 | return temp;
40 | }
41 |
42 | /** Returns whether the queue is empty. */
43 | bool empty() {
44 | return s1.empty() && s2.empty();
45 | }
46 |
47 | };
48 |
49 | /**
50 | * Your MyQueue object will be instantiated and called as such:
51 | * MyQueue* obj = new MyQueue();
52 | * obj->push(x);
53 | * int param_2 = obj->pop();
54 | * int param_3 = obj->peek();
55 | * bool param_4 = obj->empty();
56 | */
57 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 13 (Stacks and Queues)/Implement Stack using Queue.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class MyStack {
4 | public:
5 | /** Initialize your data structure here. */
6 | queue q;
7 | MyStack() {
8 | // we can do this with only 1 Queue. 2 Not needed
9 | }
10 |
11 | /** Push element x onto stack. */
12 | void push(int x) {
13 | int len = q.size();
14 | q.push(x);
15 | for(int i = 0; i != len; i++){
16 | q.push(q.front());
17 | q.pop();
18 | // basically add the new element, then pop off all the elements before it and append then behind the new ele. So new ele is in the front of Q i.e. top of "stack"
19 | }
20 | }
21 |
22 | /** Removes the element on top of the stack and returns that element. */
23 | int pop() {
24 | int temp = q.front();
25 | q.pop();
26 | return temp;
27 | }
28 |
29 | /** Get the top element. */
30 | int top() {
31 | return q.front();
32 | }
33 |
34 | /** Returns whether the stack is empty. */
35 | bool empty() {
36 | return q.empty();
37 | }
38 | };
39 |
40 | /**
41 | * Your MyStack object will be instantiated and called as such:
42 | * MyStack* obj = new MyStack();
43 | * obj->push(x);
44 | * int param_2 = obj->pop();
45 | * int param_3 = obj->top();
46 | * bool param_4 = obj->empty();
47 | */
48 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 13 (Stacks and Queues)/Next Greater Element.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | vector nextGreaterElement(vector& nums1, vector& nums2) {
4 | unordered_map m;
5 | stack s;
6 | for(int it: nums2){
7 | while(!s.empty() && it > s.top()){ // keep checking till it < top element
8 | m[s.top()] = it; // map element and its next greater ele
9 | s.pop();
10 | }
11 | s.push(it);
12 | }
13 |
14 | for(int &it: nums1){
15 | // if the element key exists (checked w count) then replace "it" with greater ele. Else -1
16 | it = m.count(it) ? m[it] : -1;
17 | }
18 | return nums1;
19 | }
20 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 14/Implement Min Stack.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | /** initialize your data structure here. */
4 | stack> stk;
5 |
6 | MinStack() {
7 |
8 | }
9 |
10 | void push(int val) {
11 | int minVal = INT_MAX;
12 | if(stk.empty()){
13 | minVal = val;
14 | } else {
15 | minVal = min(stk.top().second, val);
16 | }
17 |
18 | stk.push({val, minVal});
19 | }
20 |
21 | void pop() {
22 | stk.pop();
23 | }
24 |
25 | int top() {
26 | return stk.top().first;
27 | }
28 |
29 | int getMin() {
30 | return stk.top().second;
31 | }
32 |
33 | //Sid's solution
34 | /*returns min element from stack*/
35 | int _stack :: getMin()
36 | {
37 | //Your code here
38 | if(s.empty())
39 | return -1;
40 | else
41 | return minEle;
42 | }
43 |
44 | /*returns poped element from stack*/
45 | int _stack ::pop()
46 | {
47 | //Your code here
48 | if(s.empty())
49 | return -1;
50 | else
51 | {
52 |
53 | if(s.top() >= minEle)
54 | {
55 | int x = s.top();
56 | s.pop();
57 | return x;
58 | }
59 | else
60 | {
61 | int x = minEle;
62 | minEle = 2*x - s.top();
63 | s.pop();
64 | return x;
65 | }
66 | }
67 | }
68 |
69 | /*push element x into the stack*/
70 | void _stack::push(int x)
71 | {
72 | //Your code here
73 | if(s.empty())
74 | {
75 | minEle = x;
76 | s.push(x);
77 | }
78 | else if(x >= minEle)
79 | {
80 | s.push(x);
81 | }
82 | else
83 | {
84 | s.push(2*x-minEle);
85 | minEle = x;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 14/LRU Cache (Hard)(VVIP).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class LRUCache {
4 | public:
5 | // To add and remove ele in constant time O(1) we use linked list and not array as in array,
6 | // to shift after deletion is O(n) but not needed in LL ( head, tail ptr)
7 |
8 | // To check if element is already in cache, use hashmap (store address and value)
9 | // Hence, traversal also O(1) and not o(n)
10 | int capacity;
11 | list recent; // (front) MRU......LRU (back) has the element values
12 | unordered_map::iterator> pos; // key->iterator
13 | unordered_map cache; //key->value. key is the memory of the element value
14 |
15 | void use(int key){
16 | if(pos.find(key) != pos.end()){
17 | // key exists.
18 | recent.erase(pos[key]);
19 | } else if(recent.size() >= capacity){
20 | //remove LRU
21 | int old = recent.back();
22 | recent.pop_back();
23 | cache.erase(old); pos.erase(old);
24 | }
25 | // add new ele to front (MRU) and make it front
26 | // no need to shift back all elements before adding new ele as we are not using array
27 | recent.push_front(key);
28 | pos[key] = recent.begin();
29 | }
30 |
31 | LRUCache(int capacity) { // runs when initialized
32 | this->capacity = capacity;
33 | }
34 |
35 | int get(int key) {
36 | if(cache.find(key) != cache.end()){
37 | use(key);
38 | return cache[key];
39 | }
40 | return -1;
41 | }
42 |
43 | void put(int key, int value) {
44 | use(key);
45 | cache[key] = value;
46 | }
47 | };
48 |
49 | /**
50 | * Your LRUCache object will be instantiated and called as such:
51 | * LRUCache* obj = new LRUCache(capacity);
52 | * int param_1 = obj->get(key);
53 | * obj->put(key,value);
54 | */
55 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 14/Next Smaller Element.cpp:
--------------------------------------------------------------------------------
1 | // Sid
2 |
3 | #include
4 | using namespace std;
5 | int main()
6 | {
7 | stack s;
8 | vector x;
9 | int n;
10 | cin >> n;
11 | for(int i = 0; i < n; i++)
12 | {
13 | int a;
14 | cin >> a;
15 | x.push_back(a);
16 | }
17 | int nse[1000];
18 | for(int i = 0; i < n; i++)
19 | {
20 | if(s.empty())
21 | {
22 | s.push(i);
23 | }
24 | else
25 | {
26 | if(x[s.top()] > x[i])
27 | {
28 | while(!s.empty() && x[s.top()] > x[i])
29 | {
30 | nse[s.top()] = x[i];
31 | s.pop();
32 | }
33 | s.push(i);
34 | }
35 | else
36 | {
37 | s.push(i);
38 | }
39 | }
40 | }
41 | while(!s.empty())
42 | {
43 | nse[s.top()] = -1;
44 | s.pop();
45 | }
46 | for(int i = 0; i < n; i++)
47 | cout << nse[i] << " ";
48 | }
49 |
50 | // Hari
51 |
52 | #include
53 | using namespace std;
54 |
55 | int main() {
56 | int n;
57 | vector a;
58 |
59 | cin >> n;
60 |
61 | for(int i = 0; i> temp;
64 | a.push_back(temp);
65 | }
66 |
67 | int NSE[1000];
68 | stack s;
69 |
70 | for(int i = 0; i a[i]){
75 | while(!s.empty() && a[s.top()] > a[i]){
76 | NSE[s.top()] = a[i];
77 | s.pop();
78 | }
79 | s.push(i);
80 | }
81 | else s.push(i);
82 | }
83 |
84 | while(!s.empty()){
85 | // check if remaining elements exist and for them in NSE assign -1
86 | NSE[s.top()] = -1;
87 | s.pop();
88 | }
89 |
90 | for(int i = 0; i maxSlidingWindow(vector& nums, int k) {
4 | deque dq;
5 | vector ans;
6 |
7 | for(int curr = 0; curr dq's top, keep pop-ing it. All elements in dq < nums[curr] are removed as they have o chance of getting selected in window range
11 | while(!dq.empty() && nums[dq.back()] < nums[curr]) dq.pop_back();
12 | // now we add the nums[curr] to dq
13 | dq.push_back(curr);
14 | // the front of dq has the largest number in (curr-k, curr) window
15 | if(curr - k + 1 >= 0) ans.emplace_back(nums[dq.front()]);
16 | }
17 | return ans;
18 | }
19 |
20 |
21 | //Sid's solution
22 |
23 |
24 | class Solution {
25 | public:
26 | vector maxSlidingWindow(vector& nums, int k) {
27 | //first find the next greater element
28 | //in a window if the next greater element of an element is outside the window then tha will be the maximum element in the window. If the next greater element
29 | //exists in the window then go to the next greater element and check it again, then mark it the greatest.
30 | int nge[100000];
31 | stack s;
32 | int n = nums.size();
33 | for(int i = 0; i < n; i++)
34 | {
35 | if(s.empty())
36 | {
37 | s.push(i);
38 | }
39 | else
40 | {
41 | if(nums[i] > nums[s.top()])
42 | {
43 | while(!s.empty() && nums[i] > nums[s.top()])
44 | {
45 | nge[s.top()] = i;
46 | s.pop();
47 | }
48 | s.push(i);
49 | }
50 | else
51 | {
52 | s.push(i);
53 | }
54 | }
55 | }
56 | while(!s.empty())
57 | {
58 | nge[s.top()] = n;
59 | s.pop();
60 | }
61 | vector res;
62 | int j = 0;
63 | for(int i = 0; i <= n-k; i++)
64 | {
65 | if(j < i)
66 | {
67 | j = i;
68 | }
69 | while(nge[j] < i+k)
70 | {
71 | j = nge[j];
72 | }
73 | res.push_back(nums[j]);
74 | }
75 | return res;
76 | }
77 | };
78 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 15 (Strings)/Implement ATOI and STRSTR.cpp:
--------------------------------------------------------------------------------
1 | // ATOI (Hari) Not satisfying stupid testcases on LC. Normal tc are fine
2 |
3 | int myAtoi(string s) {
4 | int i = 0;
5 | int minVal = -2147483648;
6 | int maxVal = 2147483647;
7 | vector finalNum;
8 | for(; i 9223372036854775807) break;
30 | long long int temp = finalNum[j]*pow(10,N - j - 1);
31 | finalAns += temp;
32 | }
33 | if(sign){
34 | finalAns = -finalAns;
35 | }
36 | if(finalAns < minVal) return minVal;
37 | if(finalAns > maxVal) return maxVal;
38 | return finalAns;
39 | }
40 |
41 | // not my soln
42 |
43 | class Solution {
44 | public:
45 | int myAtoi(string str) {
46 | if (str.empty()) return 0;
47 | int i = 0, sign = 1;
48 | while (i + 1 < str.size() && isspace(str[i])) ++i;
49 | long res = 0;
50 | if (str[i] == '-' || str[i] == '+') sign = 44 - str[i++];
51 | while (i < str.size()) {
52 | if (isdigit(str[i])) res = 10 * res + str[i++] - '0';
53 | else return res * sign;
54 | if (res > INT_MAX) return sign == -1 ? INT_MIN : INT_MAX;
55 | }
56 | return res * sign;
57 | }
58 | };
59 |
60 | // STRSTR (Sid)
61 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 15 (Strings)/Longest Common Prefix.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | string helper(string s1, string s2){
6 | int t1 = 0, t2 = 0;
7 | while(t1 < s1.size() && t2 < s2.size()){
8 | if(s1[t1] == s2[t2]) {
9 | t1++;
10 | t2++;
11 | } else break;
12 | }
13 | return s1.substr(0, t1);
14 | }
15 |
16 | string longestCommonPrefix(vector& strs) {
17 | if(strs.size() == 1) return strs[0];
18 | // find the longest common prefix for first 2 strings in vector
19 | string res = helper(strs[0], strs[1]);
20 | // we get the LCP
21 | // check if this LCP exists within the rest of the strings in vector
22 | for(int i = 2; i& strs) {
45 | string res;
46 | if(strs.size() == 1)
47 | return strs[0];
48 | res = helper(strs[0], strs[1]);
49 | for(int i = 2; i < strs.size(); i++)
50 | {
51 | res = helper(res, strs[i]);
52 | }
53 | return res;
54 | }
55 | };
56 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 15 (Strings)/Longest Palindrome substring.cpp:
--------------------------------------------------------------------------------
1 | // Sid
2 | class Solution {
3 | public:
4 | string longestPalindrome(string s) {
5 | int maxLen = 1;
6 | int n = s.length();
7 | string res;
8 | int startInd = 0;
9 | //for each index, check if even or odd length palindrome can be formed from that character given the character is the pivot of the palindrome
10 | for(int i = 0; i < n; i++)
11 | {
12 | //odd palindrome
13 | int l = i - 1;
14 | int r = i + 1;
15 | while(l >= 0 && r < n && s[l] == s[r])
16 | {
17 | if(r - l + 1 > maxLen)
18 | {
19 | maxLen = r - l + 1;
20 | startInd = l;
21 | }
22 | l--;
23 | r++;
24 | }
25 | //even palindrome
26 | l = i;
27 | r = i+1;
28 | while(l >= 0 && r < n && s[l] == s[r])
29 | {
30 | if(r - l + 1 > maxLen)
31 | {
32 | maxLen = r - l + 1;
33 | startInd = l;
34 | }
35 | l--;
36 | r++;
37 | }
38 |
39 | }
40 | return s.substr(startInd, maxLen);
41 | }
42 | };
43 |
44 | // Hari
45 |
46 | string longestPalindrome(string s) {
47 | int N = s.size();
48 | int maxLen = 1; // as a single letter is also a palindrome
49 | int start = 0; // assigning the start of the longest palindrome
50 |
51 | for(int i = 0; i= 0 && r < N && s[l] == s[r]){
56 | if(r - l + 1 > maxLen){
57 | start = l;
58 | maxLen = r - l + 1;
59 | }
60 | l-- ; r++;
61 | }
62 |
63 | // check for even size palindrome from this index
64 | l = i;
65 | r = i + 1;
66 | while(l >= 0 && r < N && s[l] == s[r]){
67 | if(r - l + 1 > maxLen){
68 | start = l;
69 | maxLen = r - l + 1;
70 | }
71 | l-- ; r++;
72 | }
73 | }
74 |
75 | return s.substr(start, maxLen);
76 | }
77 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 15 (Strings)/Reverse words in String.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | string reverseWords(string s) {
4 | string ans = "";
5 | for(int i = 0; i 0) ans = " " + ans;
11 | string wordFormed = s.substr(l, i-l);
12 | ans = wordFormed + ans;
13 | }
14 | return ans;
15 | }
16 |
17 | //Sid
18 |
19 | class Solution {
20 | public:
21 | string reverseWords(string s) {
22 | int i, j;
23 | i = 0, j = 0;
24 | while(i < s.length() && j < s.length())
25 | {
26 | if(s[i] == ' ')
27 | {
28 | while(i < s.length()-1 && s[i] == s[i+1])
29 | i++;
30 | s[j] = s[i];
31 | j++;
32 | i++;
33 | }
34 | else
35 | {
36 | s[j] = s[i];
37 | j++;
38 | i++;
39 | }
40 | }
41 | s = s.substr(0,j);
42 | if(s[0] == ' ')
43 | {
44 | s = s.substr(1, s.length()-1);
45 | }
46 | if(s[s.length()-1] == ' ')
47 | {
48 | s = s.substr(0, s.length() - 1);
49 | }
50 | reverse(s.begin(), s.end());
51 | i = 0;
52 | j = 0;
53 | for(i = 0; i < s.length(); i++)
54 | {
55 | while(i < s.length() && s[i] != ' ')
56 | {
57 | i++;
58 | }
59 | int r = i - 1;
60 | i++;
61 | int l = j;
62 | while(l <= r)
63 | {
64 | swap(s[l], s[r]);
65 | l++;
66 | r--;
67 | }
68 | j = i;
69 | }
70 | return s;
71 | }
72 | };
73 |
74 |
75 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 16 (Strings)/Check for anagrams.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | bool isAnagram(string s, string t) {
4 | int freq[26] = {0};
5 | for(int i = 0; i< s.size(); i++){
6 | freq[s[i] - 'a']++;
7 | }
8 |
9 | for(int i = 0; i num2) return 1;
18 | // if both equal
19 | i++; j++;
20 | }
21 | return 0;
22 | }
23 |
24 | //Sid's solution
25 |
26 | class Solution {
27 | public:
28 |
29 | int compareVersion(string version1, string version2) {
30 | int i = 0, j = 0;
31 | int n = version1.length();
32 | int m = version2.length();
33 | vector v1, v2;
34 | string s;
35 | while(i < n)
36 | {
37 | if(version1[i] == '.')
38 | {
39 | v1.push_back(s);
40 | s.clear();
41 | }
42 | else
43 | {
44 | s.push_back(version1[i]);
45 | }
46 | i++;
47 | }
48 | v1.push_back(s);
49 | s.clear();
50 | while(j < m)
51 | {
52 | if(version2[j] == '.')
53 | {
54 | v2.push_back(s);
55 | s.clear();
56 | }
57 | else
58 | {
59 | s.push_back(version2[j]);
60 | }
61 | j++;
62 | }
63 | v2.push_back(s);
64 | s.clear();
65 | int ptr1 = 0, ptr2 = 0;
66 | while(ptr1 < v1.size() && ptr2 < v2.size())
67 | {
68 | int num1 = stoi(v1[ptr1]);
69 | int num2 = stoi(v2[ptr2]);
70 | if(num1 == num2)
71 | {
72 | ptr1++;
73 | ptr2++;
74 | }
75 | else if(num1 > num2)
76 | return 1;
77 | else
78 | return -1;
79 | }
80 | while(ptr1 < v1.size())
81 | {
82 | int num1 = stoi(v1[ptr1]);
83 | if(num1 > 0)
84 | return 1;
85 | ptr1++;
86 | }
87 | while(ptr2 < v2.size())
88 | {
89 | int num2 = stoi(v2[ptr2]);
90 | if(num2 > 0)
91 | return -1;
92 | ptr2++;
93 | }
94 | return 0;
95 | }
96 | };
97 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 16 (Strings)/Count and Say.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 | // Iterative method
3 |
4 | string countAndSay(int A) {
5 | if(A == 0) return "";
6 | if(A == 1) return "1";
7 |
8 | string ans = "1";
9 | string temp = "";
10 |
11 | while(A > 1){
12 | int N = ans.size();
13 | for(int i = 0; i + '0' but char to int -> - '0'
21 | temp.push_back((char)(ans[i]));
22 | }
23 | ans = temp;
24 | temp = "";
25 | A--;
26 | }
27 | return ans;
28 | }
29 |
30 | //Sid
31 | //Recursive solution
32 | class Solution {
33 | public:
34 | string helper(int cur, string &s, int n)
35 | {
36 | if(cur > n)
37 | return s;
38 | else if(cur == 1)
39 | {
40 | s.push_back('1');
41 | return helper(cur+1, s, n);
42 | }
43 | else
44 | {
45 | string s1;
46 | for(int i = 0; i < s.length(); i++)
47 | {
48 | int c = 1;
49 | while(i < s.length()-1 && s[i] == s[i+1])
50 | {
51 | i++;
52 | c++;
53 | }
54 | s1.push_back((char)(c+'0'));
55 | s1.push_back((char)(s[i]));
56 | }
57 | return helper(cur+1, s1, n);
58 | }
59 | }
60 | string countAndSay(int n) {
61 | string s;
62 | return helper(1, s, n);
63 | }
64 | };
65 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Bottom View Of Binary Tree.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | // Refer Top view before this. Exact same method. There, we add the first element that is in a level and then don't change it. Here, we keep updating elements in each lvl
4 | // as we traverse..so at each lvl the last element that came at that level is present
5 |
6 | //Function to return a list containing the bottom view of the given tree.
7 | vector bottomView(Node *root)
8 | {
9 | // last element you get for a particular vertical level is the element u see from bottom
10 | map m; // level and corresp element
11 | /*
12 | -2 -1 0 1 2 are the vertical levels.
13 | */
14 | queue> q; // Element and corresp. height
15 | vector res;
16 | if(!root) return res;
17 | q.push({root, 0});
18 | while(!q.empty()){
19 | Node* curr = q.front().first;
20 | int currht = q.front().second;
21 | q.pop();
22 | m[currht] = curr->data; // if val for this currht already exists, continue
23 | if(curr->left) q.push({curr->left, currht-1});
24 | if(curr->right) q.push({curr->right, currht+1});
25 | }
26 | // our map m has all the elements visible from top at each vertical level
27 | for(auto t: m){
28 | res.push_back(t.second);
29 | }
30 | return res;
31 | }
32 |
33 | // Sid
34 | //Function to return a list containing the bottom view of the given tree.
35 | vector bottomView(Node *root)
36 | {
37 | vector res;
38 | map mp;
39 | queue q1;
40 | queue q2;
41 | q1.push(root);
42 | q2.push(0);
43 | while(!q1.empty() && !q2.empty())
44 | {
45 | Node *cur = q1.front();
46 | int dist = q2.front();
47 | q1.pop();
48 | q2.pop();
49 | mp[dist] = cur->data;
50 | if(cur->left != NULL)
51 | {
52 | q1.push(cur->left);
53 | q2.push(dist-1);
54 | }
55 | if(cur->right != NULL)
56 | {
57 | q1.push(cur->right);
58 | q2.push(dist+1);
59 | }
60 | }
61 | map:: iterator it;
62 | for(it = mp.begin(); it != mp.end(); it++)
63 | {
64 | res.push_back(it->second);
65 | }
66 | return res;
67 | }
68 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Inorder Iterative.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * struct TreeNode {
4 | * int val;
5 | * TreeNode *left;
6 | * TreeNode *right;
7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {}
8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10 | * };
11 | */
12 | class Solution {
13 | public:
14 | vector inorderTraversal(TreeNode* root) {
15 | stack s;
16 | vector res;
17 | TreeNode* x = root;
18 | while(x != NULL || s.size() > 0)
19 | {
20 | while(x != NULL)
21 | {
22 | s.push(x);
23 | x = x->left;
24 | }
25 | x = s.top();
26 | s.pop();
27 | res.push_back(x->val);
28 | x = x->right;
29 | }
30 | return res;
31 | }
32 | };
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Inorder Recursive.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * struct TreeNode {
4 | * int val;
5 | * TreeNode *left;
6 | * TreeNode *right;
7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {}
8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10 | * };
11 | */
12 | class Solution {
13 | public:
14 | void helper(TreeNode *root, vector &res)
15 | {
16 | if(root == NULL)
17 | {
18 | return;
19 | }
20 | helper(root->left, res);
21 | res.push_back(root->val);
22 | helper(root->right, res);
23 | }
24 | vector inorderTraversal(TreeNode* root) {
25 | vector res;
26 | helper(root, res);
27 | return res;
28 | }
29 | };
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Inorder Traversal(both).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | void helper(TreeNode* root, vector &res){ // Recursive
4 | if(root == nullptr) return;
5 | else {
6 | helper(root->left, res);
7 | res.push_back(root->val);
8 | helper(root->right, res);
9 | }
10 | }
11 |
12 |
13 | vector inorderTraversal(TreeNode* root) {
14 | // Iterative
15 | // stack s;
16 | // vector res;
17 | // TreeNode* curr = root;
18 |
19 | // while(curr != NULL || !s.empty()){
20 | // while(curr != NULL){
21 | // s.push(curr);
22 | // curr = curr->left;
23 | // }
24 | // // when NULL is reached
25 | // curr = s.top();
26 | // res.emplace_back(curr->val);
27 | // curr = curr->right;
28 | // s.pop();
29 | // }
30 | // return res;
31 |
32 | // Recursive
33 | vector res;
34 | helper(root, res);
35 | return res;
36 | }
37 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Left View Of Binary Tree.cpp:
--------------------------------------------------------------------------------
1 | //Sid solution
2 | void helper(Node *root, int level, int &maxLevel, vector &res)
3 | {
4 | if(root == NULL)
5 | return;
6 | if(level > maxLevel)
7 | {
8 | maxLevel = level;
9 | res.push_back(root->data);
10 | }
11 | helper(root->left, level+1, maxLevel, res);
12 | helper(root->right, level+1, maxLevel, res);
13 | }
14 | vector leftView(Node *root)
15 | {
16 | vector res;
17 | int level = 0, maxLevel = INT_MIN;
18 | helper(root, level, maxLevel, res);
19 | return res;
20 | }
21 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Postorder (both).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | // void helper(TreeNode* root, vector &res){ // Recursive
4 | // if(root == nullptr) return;
5 | // helper(root->left, res);
6 | // helper(root->right, res);
7 | // res.push_back(root->val);
8 | // }
9 |
10 | vector postorderTraversal(TreeNode* root) {
11 | // vector res; // Recursive
12 | // helper(root, res);
13 | // return res;
14 |
15 | // Iterative
16 | stack s;
17 | vector res;
18 | if(root == nullptr) return res;
19 | s.push(root);
20 | while(!s.empty()){
21 | TreeNode* curr = s.top();
22 | res.push_back(curr->val); s.pop();
23 | // In Postorder it is left->right->root. The reverse of this is root->right->left...which is a partial reverse of Preorder(root->left->right)
24 | // So in preorder we pushed right to stack and then left. Here, do the opposite
25 | if(curr->left) s.push(curr->left);
26 | if(curr->right) s.push(curr->right);
27 | }
28 | reverse(res.begin(), res.end());
29 | return res;
30 | }
31 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Postorder Iterative.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * struct TreeNode {
4 | * int val;
5 | * TreeNode *left;
6 | * TreeNode *right;
7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {}
8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10 | * };
11 | */
12 | class Solution {
13 | public:
14 | vector helper(TreeNode *root)
15 | {
16 | vector res;
17 | if(root == NULL)
18 | return res;
19 | stack s;
20 | s.push(root);
21 | while(s.size() > 0)
22 | {
23 | TreeNode *x = s.top();
24 | res.push_back(x->val);
25 | s.pop();
26 | if(x->left != NULL)
27 | s.push(x->left);
28 | if(x->right != NULL)
29 | s.push(x->right);
30 | }
31 | reverse(res.begin(), res.end());
32 | return res;
33 | }
34 | vector postorderTraversal(TreeNode* root) {
35 | vector res = helper(root);
36 | return res;
37 | }
38 | };
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Postorder Recursive.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * struct TreeNode {
4 | * int val;
5 | * TreeNode *left;
6 | * TreeNode *right;
7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {}
8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10 | * };
11 | */
12 | class Solution {
13 | public:
14 | void helper(TreeNode *root, vector &res)
15 | {
16 | if(root == NULL)
17 | return;
18 | helper(root->left, res);
19 | helper(root->right, res);
20 | res.push_back(root->val);
21 | }
22 | vector postorderTraversal(TreeNode* root) {
23 | vector res;
24 | helper(root, res);
25 | return res;
26 | }
27 | };
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Preorder (both).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | // void helper(TreeNode* root, vector &res){ //Recursive
4 | // if(root == nullptr) return;
5 | // res.push_back(root->val);
6 | // helper(root->left, res);
7 | // helper(root->right, res);
8 | // }
9 | vector preorderTraversal(TreeNode* root) {
10 | // Recursive
11 | // vector res;
12 | // helper(root, res);
13 | // return res;
14 |
15 | //Iterative
16 | stack s;
17 | vector res;
18 | if(root == nullptr) return res;
19 | s.push(root);
20 | while(!s.empty()){
21 | TreeNode* curr = s.top();
22 | res.push_back(curr->val);
23 | s.pop();
24 | // Push right first then left as stack is LIFO
25 | if(curr->right) s.push(curr->right);
26 | if(curr->left) s.push(curr->left);
27 | }
28 | return res;
29 | }
30 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Preorder Iterative.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * struct TreeNode {
4 | * int val;
5 | * TreeNode *left;
6 | * TreeNode *right;
7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {}
8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10 | * };
11 | */
12 | class Solution {
13 | public:
14 | vector preorderTraversal(TreeNode* root) {
15 | vector res;
16 | if(root == NULL)
17 | {
18 | return res;
19 | }
20 |
21 | stack s;
22 | s.push(root);
23 | while(s.size() > 0)
24 | {
25 | TreeNode *cur = s.top();
26 | res.push_back(cur->val);
27 | s.pop();
28 | if(cur->right != NULL)
29 | s.push(cur->right);
30 | if(cur->left != NULL)
31 | s.push(cur->left);
32 | }
33 | return res;
34 | }
35 | };
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Preorder Recursive.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Definition for a binary tree node.
3 | * struct TreeNode {
4 | * int val;
5 | * TreeNode *left;
6 | * TreeNode *right;
7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {}
8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
10 | * };
11 | */
12 | class Solution {
13 | public:
14 | void helper(TreeNode *root, vector &res)
15 | {
16 | if(root == NULL)
17 | return;
18 | res.push_back(root->val);
19 | helper(root->left, res);
20 | helper(root->right, res);
21 | }
22 | vector preorderTraversal(TreeNode* root) {
23 | vector res;
24 | helper(root, res);
25 | return res;
26 | }
27 | };
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Right View of Binary Tree.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | vector rightSideView(TreeNode* root) {
4 | vector res;
5 | queue q;
6 | if(root == nullptr) return res;
7 | q.push(root);
8 | while(!q.empty()){
9 | int N = q.size();
10 | for(int i = 1; i<=N; i++){
11 | TreeNode* curr = q.front(); q.pop();
12 | if(i == N) res.push_back(curr->val);
13 | if(curr->left) q.push(curr->left);
14 | if(curr->right) q.push(curr->right);
15 | }
16 | }
17 | return res;
18 | }
19 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 17 (Binary Tree)/Top View Of Binary Tree.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution
4 | {
5 | public:
6 | //Function to return a list of nodes visible from the top view
7 | //from left to right in Binary Tree.
8 | vector topView(Node *root)
9 | {
10 | // first element you get for a particular vertical level is the element u see from top
11 | map m; // level and corresp element
12 | /*
13 | -2 -1 0 1 2 are the vertical levels.
14 | If element is in a level and current val for that level is 0, then add this element to
15 | that level. Else, that element is not visible at that level. So, continue
16 | */
17 | queue> q; // Element and corresp. height
18 | vector res;
19 | if(!root) return res;
20 | q.push({root, 0});
21 | while(!q.empty()){
22 | Node* curr = q.front().first;
23 | int currht = q.front().second;
24 | q.pop();
25 | if(!m[currht]) m[currht] = curr->data; // if val for this currht already exists, continue
26 | if(curr->left) q.push({curr->left, currht-1});
27 | if(curr->right) q.push({curr->right, currht+1});
28 | }
29 | // our map m has all the elements visible from top at each vertical level
30 | for(auto t: m){
31 | res.push_back(t.second);
32 | }
33 | return res;
34 |
35 | }
36 |
37 | };
38 |
39 | // Sid
40 |
41 | class Solution
42 | {
43 | public:
44 | //Function to return a list of nodes visible from the top view
45 | //from left to right in Binary Tree.
46 | vector topView(Node *root)
47 | {
48 | map mp;
49 | //we ll be doing level order traversal and updating the horizontal distances from the root
50 | queue q1; // queue to store the horizontal distances of nodes from root
51 | queue q2;//queue to store the nodes from the root
52 | q2.push(root);
53 | q1.push(0);
54 | while(!q1.empty() && !q2.empty())
55 | {
56 | Node *cur = q2.front();
57 | int dist = q1.front();
58 | q1.pop();
59 | q2.pop();
60 | if(mp.count(dist) == 0)
61 | {
62 | //if the distance hasnt been encountered yet then add it as it means it's the first occurrence
63 | mp[dist] = cur->data;
64 | }
65 | if(cur->left != NULL)
66 | {
67 | q2.push(cur->left);
68 | q1.push(dist-1);
69 | }
70 | if(cur->right != NULL)
71 | {
72 | q2.push(cur->right);
73 | q1.push(dist+1);
74 | }
75 |
76 | }
77 | vector res;
78 | map::iterator it;
79 | for(it = mp.begin(); it != mp.end(); it++)
80 | {
81 | res.push_back(it->second);
82 | }
83 | return res;
84 | }
85 |
86 | };
87 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 18 (Binary Tree)/Check if trees identical.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | bool isSameTree(TreeNode* p, TreeNode* q) {
6 | // check if nodes are none or not, then if value matches or not. If value matches, check if they are in the same subtree / position in their resp. tree
7 |
8 | // base cases
9 | if(!p && !q) return true; // both nullptr then valid
10 | else if(!p || !q) return false; // only one of them is null
11 | else if(p->val != q->val) return false; // nodes exist but diff values
12 | else return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); // nodes are the same. Now compare their subtrees and if any one of them don't match then invalid
13 | }
14 | };
15 |
16 | //Sid
17 | bool isSameTree(TreeNode* p, TreeNode* q) {
18 | if(p == NULL && q == NULL)
19 | return true;
20 | else if(p == NULL || q == NULL)
21 | return false;
22 | bool l = isSameTree(p->left, q->left);
23 | bool r = isSameTree(p->right, q->right);
24 | if(p->val == q->val && l && r)
25 | return true;
26 | return false;
27 | }
28 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 18 (Binary Tree)/Diameter of tree.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | int helper(TreeNode* curr, int &d){
4 | if(curr == nullptr) return 0;
5 |
6 | int left = helper(curr->left, d);
7 | int right = helper(curr->right, d);
8 |
9 | d = max(d, left+right); // keeps check of maxDia for each node and at the end it will have maxDia for whole tree
10 | return max(left, right) + 1; // for next lvl (see finding maxDepth qn)
11 | }
12 |
13 | int diameterOfBinaryTree(TreeNode* root) {
14 | // In finding ht of tree, we just calc max ht for each node by finding max depth of its left and right node + 1 (curr node) and return this val for the next level
15 | // For dia, its very similar to this. Max dia = max(dia, left+right)
16 | int maxDia = 0;
17 | helper(root, maxDia);
18 | return maxDia;
19 |
20 | }
21 |
22 | //Sid
23 | int diameter(TreeNode* root, int &h)
24 | {
25 | if(root == NULL)
26 | return 0;
27 | int lh = 0, rh = 0;
28 | int ld = diameter(root->left, lh);
29 | int rd = diameter(root->right, rh);
30 | h = max(lh, rh) + 1;
31 | return max(lh+rh, max(ld, rd));
32 | }
33 | int diameterOfBinaryTree(TreeNode* root) {
34 | int h = 0;
35 | return diameter(root, h);
36 | }
37 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 18 (Binary Tree)/Height balanced Check.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | // Check if BTree is height balanced or not
4 |
5 | class Solution {
6 | public:
7 | int htBalChk = 1;
8 | int helper(TreeNode* curr){
9 | if(!curr) return 0;
10 | int left = helper(curr->left);
11 | int right = helper(curr->right);
12 | if(abs(left - right) > 1) htBalChk = 0;
13 | return max(left, right) + 1; // next level
14 | }
15 |
16 | bool isBalanced(TreeNode* root) {
17 | htBalChk = 1; // assume its ht balanced initially
18 | helper(root);
19 | return htBalChk;
20 | }
21 | };
22 |
23 | //Sid
24 | bool helper(TreeNode *root, int &h)
25 | {
26 | if(root == NULL)
27 | {
28 | h = 0;
29 | return true;
30 | }
31 | int lh = 0, rh = 0;
32 | bool l = helper(root->left, lh);
33 | bool r = helper(root->right, rh);
34 | h = max(lh, rh) + 1;
35 | if(l && r && abs(lh-rh) <= 1)
36 | return true;
37 | else
38 | return false;
39 | }
40 | bool isBalanced(TreeNode* root) {
41 | int height = 0;
42 | return helper(root, height);
43 | }
44 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 18 (Binary Tree)/Height of Binary Tree.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | int maxDepth(TreeNode* root) {
4 | // if(root == nullptr) return 0; //base case when we reach a leaf
5 |
6 | // int left = maxDepth(root->left);
7 | // int right = maxDepth(root->right);
8 |
9 | // return max(left, right) + 1; // add curr level also
10 | // Exact thing but in 1 line
11 | return root == NULL ? 0 : max(maxDepth(root -> left), maxDepth(root -> right)) + 1;
12 | }
13 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 18 (Binary Tree)/LCA in Binary Tree.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
6 | if(!root || root == p || root == q) return root;
7 |
8 | TreeNode* left = lowestCommonAncestor(root->left, p, q);
9 | TreeNode* right = lowestCommonAncestor(root->right, p, q);
10 |
11 | if(left && right) return root; // if both l and r exist for a node, that node is the LCA. If one of them is null, just pass the non null val up so that the LCA can be found in the future above.
12 | if(left) return left;
13 | else return right;
14 | }
15 | };
16 |
17 |
18 | //Sid
19 | bool nodeToRoot(TreeNode* root, vector &path, TreeNode *x)
20 | {
21 | if(root == NULL)
22 | return false;
23 | if(root == x)
24 | {
25 | path.push_back(root);
26 | return true;
27 | }
28 | bool l = nodeToRoot(root->left, path, x);
29 | if(l)
30 | {
31 | path.push_back(root);
32 | return true;
33 | }
34 | bool r = nodeToRoot(root->right, path, x);
35 | if(r)
36 | {
37 | path.push_back(root);
38 | return true;
39 | }
40 | return false;
41 | }
42 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
43 | vector path1, path2;
44 | bool e1 = nodeToRoot(root, path1, p);
45 | bool e2 = nodeToRoot(root, path2, q);
46 | int i = 0, j = 0;
47 | reverse(path1.begin(), path1.end());
48 | reverse(path2.begin(), path2.end());
49 | while(i < path1.size() && j < path2.size())
50 | {
51 | if(path1[i] == path2[j])
52 | {
53 | i++;
54 | j++;
55 | }
56 | else
57 | break;
58 | }
59 | return path1[i-1];
60 | }
61 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 18 (Binary Tree)/Level Order Traversal.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | vector> levelOrder(TreeNode* root) {
4 | vector> res;
5 | if(root == nullptr) return res;
6 |
7 | queue q;
8 | q.push(root);
9 | while(!q.empty()){
10 | int N = q.size();
11 | vector currlvl;
12 | for(int i = 0; ival);
16 | if(curr->left) q.push(curr->left);
17 | if(curr->right) q.push(curr->right);
18 | }
19 | res.push_back(currlvl);
20 | }
21 | return res;
22 | }
23 |
24 | //Sid
25 | int height(TreeNode *root)
26 | {
27 | if(root == NULL)
28 | return 0;
29 | int lh = height(root->left);
30 | int rh = height(root->right);
31 | return max(lh,rh)+1;
32 | }
33 | void helper(TreeNode *root, int level, vector &res)
34 | {
35 | if(root == NULL)
36 | return;
37 | if(level == 0)
38 | {
39 | res.push_back(root->val);
40 | return;
41 | }
42 | helper(root->left, level-1, res);
43 | helper(root->right, level-1, res);
44 | }
45 | vector> levelOrder(TreeNode* root) {
46 | vector> x;
47 | int h = height(root);
48 | for(int i = 0; i < h; i++)
49 | {
50 | vector temp;
51 | helper(root, i, temp);
52 | x.push_back(temp);
53 | }
54 | return x;
55 | }
56 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 18 (Binary Tree)/Level order in Spiral.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | vector> zigzagLevelOrder(TreeNode* root) {
4 | vector> res;
5 | if(root == nullptr) return res;
6 |
7 | bool reverse = false; // reverse the vector if true
8 |
9 | queue q;
10 | q.push(root);
11 | while(!q.empty()){
12 | int N = q.size();
13 | vector currlvl(N, 0);
14 | for(int i = 0; ival;
19 | else {
20 | currlvl[N-i-1] = curr->val; // adding from behind
21 | }
22 | if(curr->left) q.push(curr->left);
23 | if(curr->right) q.push(curr->right);
24 | }
25 | res.push_back(currlvl);
26 | reverse = !reverse; // for next level, negate it
27 | }
28 | return res;
29 | }
30 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 19 (Binary Tree)/Construct BTree from Inorder and Postorder.cpp:
--------------------------------------------------------------------------------
1 | // Slight modification of Inorder and Preorder. Traverse from back instead of front as it is postorder
2 |
3 | // Hari
4 |
5 | class Solution {
6 | public:
7 | int idx = 0;
8 | unordered_map m;
9 |
10 | TreeNode* helper(vectorinorder, vectorpostorder, int start, int end, int &idx){
11 | if(start > end || idx < 0) return nullptr;
12 | TreeNode* curr = new TreeNode(postorder[idx--]);
13 | // for leaf node
14 | if(start == end) return curr;
15 | // search this element in inorder
16 | int mid = m[curr->val]; //gives the index of curr
17 | //recursive calls
18 | curr->right = helper(inorder, postorder, mid+1, end, idx);
19 | curr->left = helper(inorder, postorder, start, mid-1, idx);
20 | return curr;
21 | }
22 |
23 | TreeNode* buildTree(vector& inorder, vector& postorder) {
24 | // postorder gives us the parent each time when coming from back.
25 | //Search this parent in inorder using map O(1)
26 | // and left of this in left subtree, right in right subtree
27 | int N = inorder.size();
28 | idx = N-1;
29 | m.clear();
30 | // filling map using inorder elements
31 | for(int i = 0; i postorder, vector inorder, int &postInd, int l, int r)
42 | {
43 | if(postInd < 0 || r < l)
44 | return NULL;
45 | TreeNode *root = new TreeNode(postorder[postInd]);
46 | postInd--;
47 | if(l == r)
48 | return root;
49 | int i;
50 | for(i = 0; i < inorder.size(); i++)
51 | {
52 | if(inorder[i] == root->val)
53 | break;
54 | }
55 | root->right = build(postorder, inorder, postInd, i+1, r);
56 | root->left = build(postorder, inorder, postInd, l, i-1);
57 |
58 |
59 |
60 | return root;
61 | }
62 | TreeNode* buildTree(vector& inorder, vector& postorder) {
63 | //OM GAN GANAPATHAYE NAMO NAMAH
64 | //JAI SHRI RAM
65 | //JAI BAJRANGBALI
66 | //AMME NARAYANA. DEVI NARAYANA, LAKSHMI NARAYANA, BHADRE NARAYANA
67 | int postInd = postorder.size() - 1;
68 | int l = 0, r = inorder.size() - 1;
69 | return build(postorder, inorder, postInd, l, r);
70 | }
71 | };
72 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 19 (Binary Tree)/Construct BTree from Inorder and Preorder(Hard).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | int idx = 0;
6 | unordered_map m;
7 |
8 | TreeNode* helper(vectorpreorder, vectorinorder, int start, int end){
9 | // traverse preorder
10 | if(start > end) return nullptr; // base case
11 | TreeNode* curr = new TreeNode(preorder[idx++]);
12 | if(start == end) return curr; // when leaf node added
13 | int mid = m[curr->val]; // get parent index.
14 | curr->left = helper(preorder, inorder, start, mid-1);
15 | curr->right = helper(preorder, inorder, mid+1, end);
16 | return curr;
17 | }
18 |
19 | TreeNode* buildTree(vector& preorder, vector& inorder) {
20 | // preorder gives us the parent each time. Search this parent in inorder
21 | // (using map O(1)) and left of this in left subtree, right in right subtree
22 | idx = 0;
23 | m.clear();
24 | int N = inorder.size();
25 | // filling map using inorder elements
26 | for(int i = 0; ileft == nullptr && A->right == nullptr) return;
9 | if(A->left){
10 | helper(A->left); // we will go till 3, and as next left is null, we will go up to 2 and then go to 4.
11 | TreeNode* temp = A->right;
12 | A->right = A->left;
13 | A->left = nullptr;
14 |
15 | TreeNode* curr = A->right;
16 | while(curr->right) curr = curr->right;
17 | //merge the old right
18 | curr->right = temp;
19 | }
20 | helper(A->right);
21 | }
22 | void flatten(TreeNode* root) {
23 | helper(root);
24 | }
25 | };
26 |
27 | //Sid
28 | void flatten(TreeNode* root) {
29 | if(root == NULL || (root->left == NULL && root->right == NULL))
30 | return;
31 | if(root->left != NULL)
32 | {
33 | flatten(root->left);
34 | TreeNode *temp = root->right;
35 | root->right = root->left;
36 | root->left = NULL;
37 | TreeNode *cur = root->right;
38 | while(cur->right != NULL)
39 | {
40 | cur = cur->right;
41 | }
42 | cur->right = temp;
43 |
44 | }
45 | flatten(root->right);
46 | }
47 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 19 (Binary Tree)/Maximum Path Sum(Hard).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | // Best explanation: https://www.youtube.com/watch?v=6cA_NDtpyz8&ab_channel=MichaelMuinosMichaelMuinos
5 | public:
6 | int maxP = INT_MIN;
7 |
8 | int helper(TreeNode* curr){
9 | // do postorder traversal standard
10 | if(curr == nullptr) return 0;
11 |
12 | //If result is -ve val, we won't send this val to curr. Send 0 instead
13 | int left = max(0,helper(curr->left));
14 | int right = max(0,helper(curr->right));
15 | // when coming out of recursive calls we find new maxP
16 |
17 | maxP = max(maxP, left + right + curr->val);
18 | // maxP gets compared, updated with maxP value of curr's subtrees
19 |
20 | return max(left, right) + curr->val;
21 | // Return value will be used to check maxP considering tree's main root in path.
22 |
23 | }
24 |
25 | int maxPathSum(TreeNode* root) {
26 | helper(root);
27 | return maxP;
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 19 (Binary Tree)/Symmetric Tree(Mirror of itself).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | bool helper(TreeNode* r1, TreeNode* r2){
6 | if(!r1 && !r2) return true;
7 | if(!r1 || !r2) return false;
8 |
9 | if(r1 && r2 && r1->val == r2->val){
10 | // check their subtrees
11 | return helper(r1->left, r2->right) && helper(r1->right, r2->left);
12 | }
13 | return false;
14 | }
15 |
16 |
17 | bool isSymmetric(TreeNode* root) {
18 | return helper(root, root);
19 | }
20 | };
21 |
22 | //Sid
23 | bool helper(TreeNode *root1, TreeNode *root2)
24 | {
25 | if(root1 == NULL && root2 == NULL)
26 | return true;
27 | else if(root1 == NULL || root2 == NULL)
28 | return false;
29 | bool x = helper(root1->left, root2->right);
30 | bool y = helper(root1->right, root2->left);
31 | if(root1->val == root2->val && x && y)
32 | return true;
33 | return false;
34 | }
35 | bool isSymmetric(TreeNode* root) {
36 | //OM GAN GANAPATHAYE NAMO NAMAH
37 | //JAI SHRI RAM
38 | //JAI BAJRANGBALI
39 | //AMME NARAYANA, DEVI NARAYANA, LAKSHMI NARAYANA, BHADRE NARAYANA
40 | return helper(root->left, root->right);
41 | }
42 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 2 (Arrays)/Best Time to Buy and Sell Stock - 1.cpp:
--------------------------------------------------------------------------------
1 | class Solution {
2 | public:
3 | int maxProfit(vector& prices) {
4 | int max_profit = 0, min_price = INT_MAX;
5 | int N = prices.size();
6 |
7 | for(int i = 0; i right[j])
26 | {
27 | a[k] = right[j];
28 | count = count + (n1-i);
29 | j++;
30 | k++;
31 | }
32 | else
33 | {
34 | a[k] = left[i];
35 | i++;
36 | k++;
37 | }
38 | }
39 | while(i < n1 )
40 | {
41 | a[k] = left[i];
42 | i++;
43 | k++;
44 | }
45 | while(j < n2)
46 | {
47 | a[k] = right[j];
48 | j++;
49 | k++;
50 | }
51 | return count;
52 |
53 | }
54 | long long int inversions(long long int a[], long long int l, long long int r)
55 | {
56 | long long int count = 0;
57 | if(r > l)
58 | {
59 | long long int mid = l + (r-l)/2;
60 | count += inversions(a, l, mid);
61 | count += inversions(a, mid+1, r);
62 | count += merge(a, l, mid, r);
63 | }
64 | return count;
65 | }
66 | long long int inversionCount(long long arr[], long long N)
67 | {
68 | // Your Code Here
69 | return inversions(arr, 0, N-1);
70 | }
71 |
72 | };
73 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 2 (Arrays)/Next Permutation.cpp:
--------------------------------------------------------------------------------
1 | class Solution {
2 | public:
3 | void nextPermutation(vector& nums) {
4 | int N = nums.size(), ind = -1;
5 | for(int i = N-1; i>0; i--){
6 | if(nums[i-1] < nums[i]){
7 | ind = i-1;
8 | break;
9 | }
10 | }
11 |
12 | if(ind == -1) reverse(nums.begin(), nums.end());
13 | else {
14 | // check smallest no > nums[ind]
15 | int minIdx;
16 | for(int i = N-1; i>ind; i--){
17 | if(nums[i] > nums[ind]){
18 | minIdx = i;
19 | break;
20 | }
21 | }
22 |
23 | swap(nums[minIdx], nums[ind]);
24 |
25 | reverse(nums.begin() + ind + 1, nums.end());
26 | }
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 2 (Arrays)/Pascal Triangle. cpp:
--------------------------------------------------------------------------------
1 | class Solution {
2 | public:
3 | vector> generate(int numRows) {
4 | vector> res;
5 | for(int line = 1; line <= numRows; line++){
6 | int C = 1; // all lines start w 1
7 | vector temp;
8 | for(int i = 1; i <= line; i++){
9 | temp.push_back(C);
10 | C = C * (line - i)/i;
11 | }
12 | res.push_back(temp);
13 | temp.clear();
14 | }
15 | return res;
16 | }
17 | };
18 |
19 | // Another method
20 |
21 | class Solution {
22 | public:
23 | vector> generate(int numRows) {
24 | vector> pascal;
25 | vector temp;
26 | temp.push_back(1);
27 | pascal.push_back(temp);
28 | for(int i = 1; i < numRows; i++)
29 | {
30 | temp.clear();
31 | int size = i + 1;
32 | for(int j = 0; j < size; j++)
33 | {
34 | if(j == 0 || j == size - 1)
35 | temp.push_back(1);
36 | else
37 | {
38 | int x = pascal[i-1][j] + pascal[i-1][j-1];
39 | temp.push_back(x);
40 | }
41 | }
42 | pascal.push_back(temp);
43 | }
44 | return pascal;
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 2 (Arrays)/Rotate Matrix.cpp:
--------------------------------------------------------------------------------
1 | class Solution {
2 | public:
3 | void rotate(vector>& matrix) {
4 | // to turn clockwise -> do transpose and then reverse each row
5 | int N = matrix.size();
6 |
7 | for(int i = 0; i>& matrix) {
2 | bool rowFlag = false;
3 | bool colFlag = false;
4 | //scan the first row
5 | for(int i = 0; i < matrix[0].size(); i++)
6 | {
7 | if(matrix[0][i] == 0)
8 | rowFlag = true;
9 | }
10 | //scan the first column
11 | for(int i = 0; i < matrix.size(); i++)
12 | {
13 | if(matrix[i][0] == 0)
14 | colFlag = true;
15 | }
16 | for(int i = 1; i < matrix.size(); i++)
17 | {
18 | for(int j = 1; j < matrix[i].size(); j++)
19 | {
20 | if(matrix[i][j] == 0)
21 | {
22 | matrix[i][0] = 0;
23 | matrix[0][j] = 0;
24 | }
25 | }
26 | }
27 | for(int i = 1; i < matrix.size(); i++)
28 | {
29 | for(int j = 1; j < matrix[i].size(); j++)
30 | {
31 | if(matrix[i][0] == 0 || matrix[0][j] == 0)
32 | {
33 | matrix[i][j] = 0;
34 | }
35 | }
36 | }
37 | if(rowFlag ==true)
38 | {
39 | for(int i = 0; i < matrix[0].size(); i++)
40 | {
41 | matrix[0][i] = 0;
42 | }
43 | }
44 | if(colFlag == true)
45 | {
46 | for(int i = 0; i < matrix.size(); i++)
47 | matrix[i][0] = 0;
48 | }
49 | }
50 |
51 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 20 (BST)/Check if BT is BST.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | bool helper(TreeNode* root, TreeNode* minNode, TreeNode* maxNode){
6 | if(root == nullptr) return true; //leaf reached
7 | else if(maxNode && root->val >= maxNode->val || minNode && root->val <= minNode->val) {
8 | return false;
9 | }
10 | return helper(root->left, minNode, root) && helper(root->right, root, maxNode);
11 | }
12 |
13 | bool isValidBST(TreeNode* root) {
14 | return helper(root, NULL, NULL);
15 | }
16 | };
17 |
18 |
19 | //Sid
20 |
21 | class Solution {
22 | public:
23 | bool helper(TreeNode *root, long long int min, long long int max)
24 | {
25 | if(root == NULL)
26 | return true;
27 | if(root->val < max && root->val > min)
28 | {
29 | if(helper(root->left, min, root->val) && helper(root->right, root->val, max))
30 | return true;
31 | else
32 | return false;
33 | }
34 | else
35 | return false;
36 | }
37 | bool isValidBST(TreeNode* root) {
38 | return helper(root, LONG_MIN, LONG_MAX);
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 20 (BST)/Construct BST from given keys.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | TreeNode* bstFromPreorder(vector& preorder) {
6 | // we use stack to keep conteact of last node added. This way, no need to
7 | //start from root again and again to comapre each element
8 | TreeNode* root = new TreeNode(preorder[0]);
9 | stack s;
10 | s.push(root);
11 |
12 | for(int i = 1; ival > preorder[i]){
15 | // add this preorder element to left of root (curr)
16 | TreeNode* newNode = new TreeNode(preorder[i]);
17 | curr->left = newNode;
18 | s.push(newNode);
19 | } else {
20 | // if predorder element is > than curr root, it may be greater than root of curr root also. Check it, and when this condt fails add it there
21 | while(!s.empty() && s.top()->val < preorder[i]){
22 | curr = s.top(); s.pop();
23 | }
24 | // when preorder ele less than a stack ele and comes out of while,
25 | // the curr will show last node which can host preorder ele in right
26 |
27 | TreeNode* newNode = new TreeNode(preorder[i]);
28 | curr->right = newNode;
29 | s.push(newNode);
30 | }
31 | }
32 | return root;
33 | }
34 | };
35 |
36 | //Sid
37 | class Solution {
38 | public:
39 | TreeNode *helper(ListNode *start, ListNode *end)
40 | {
41 | if(start == end)
42 | {
43 | return NULL;
44 | }
45 | if(start->next == end)
46 | {
47 | TreeNode *root = new TreeNode(start->val);
48 | return root;
49 | }
50 | ListNode *slow = start, *fast = start;
51 | while(fast != end && fast->next != end)
52 | {
53 | slow = slow->next;
54 | fast = fast->next->next;
55 | }
56 | TreeNode *root = new TreeNode(slow->val);
57 | root->left = helper(start, slow);
58 | root->right = helper(slow->next, end);
59 | return root;
60 | }
61 | TreeNode* sortedListToBST(ListNode* head) {
62 | ListNode *start = head, *end = NULL;
63 | return helper(start, end);
64 | }
65 | };
66 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 20 (BST)/Inorder predecessor and succ in BST.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | // This function finds predecessor and successor of key in BST.
4 | // It sets pre and suc as predecessor and successor respectively
5 | void findPreSuc(Node* root, Node*& pre, Node*& suc, int key)
6 | {
7 | // base condition
8 | if (!root) return ;
9 |
10 | // target node found
11 | if (root->key == key)
12 | {
13 | if (root->left)
14 | {
15 | Node* curr = root->left; // inorder predecessor
16 | while (curr->right) // rightmost node in left subT
17 | curr = curr->right;
18 | pre = curr ;
19 | }
20 |
21 | if (root->right)
22 | {
23 | Node* curr = root->right ; // inorder successor
24 | while (curr->left) // leftmost node in right subT
25 | curr = curr->left ;
26 | suc = curr ;
27 | }
28 | return ;
29 | }
30 |
31 | if (root->key > key)
32 | {
33 | suc = root ;
34 | findPreSuc(root->left, pre, suc, key) ;
35 | }
36 | else
37 | {
38 | pre = root ;
39 | findPreSuc(root->right, pre, suc, key) ;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 20 (BST)/LCA of BST.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
6 | // This is for normal BT. BST property not used
7 | // if(!root) return nullptr;
8 | // if(root == p || root == q) return root;
9 |
10 | // TreeNode* left = lowestCommonAncestor(root->left, p,q);
11 | // TreeNode* right = lowestCommonAncestor(root->right, p,q);
12 |
13 | // if(left && right) return root;
14 | // if(left) return left;
15 | // else return right;
16 |
17 | // BST usage
18 | // we keep recursing till p and q split up. That place is the LCA of BST
19 | if(root->val < p->val && root->val < q->val) return lowestCommonAncestor(root->right,p,q);
20 | if(root->val > p->val && root->val > q->val) return lowestCommonAncestor(root->left,p,q);
21 | return root;
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 20 (BST)/Populate next right pointers.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | // trace it, you will get it
6 | void assignLowerLvl(Node* start){
7 | Node* curr = start;
8 | while(curr){
9 | curr->left->next = curr->right;
10 | if(curr->next){
11 | curr->right->next = curr->next->left;
12 | }
13 | curr = curr->next;
14 | }
15 | }
16 | Node* connect(Node* root) {
17 | // initially all next are NULL.
18 | Node* leftNode = root;
19 | while(leftNode && leftNode->left){
20 | assignLowerLvl(leftNode);
21 | leftNode = leftNode->left;
22 | }
23 | return root;
24 | }
25 | };
26 |
27 | //Sid
28 | class Solution {
29 | public:
30 | Node* connect(Node* root) {
31 | if(root == NULL || root->left == NULL || root->right == NULL)
32 | return root;
33 | //connection part
34 | root->left->next = root->right;
35 | if(root->next != NULL)
36 | {
37 | root->right->next = root->next->left;
38 | }
39 | connect(root->left);
40 | connect(root->right);
41 | return root;
42 | }
43 | };
44 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 20 (BST)/Search in BST.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | TreeNode* searchBST(TreeNode* root, int val) {
6 | TreeNode* curr = root;
7 | while(curr){
8 | if(curr->val == val) return curr; //base
9 | else if(curr->val < val){
10 | curr = curr->right;
11 | }
12 | else curr = curr->left;
13 | }
14 | return nullptr;
15 | }
16 | };
17 |
18 | //Sid
19 | class Solution {
20 | public:
21 | TreeNode* searchBST(TreeNode* root, int val) {
22 | if(root == NULL)
23 | return root;
24 | if(root->val == val)
25 | return root;
26 | else if(root->val > val)
27 | {
28 | return searchBST(root->left, val);
29 | }
30 | else
31 | {
32 | return searchBST(root->right, val);
33 | }
34 | }
35 | };
36 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 21 (BST)/BST Iterator.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class BSTIterator {
4 | public:
5 | // while a list can be used to iterate tree, store value and check
6 | // space will be O(N). We will do partial inorder w stack for O(h)
7 | stack s;
8 | BSTIterator(TreeNode* root) {
9 | helper(root);
10 | }
11 |
12 | void helper(TreeNode* curr){
13 | // move left as per inorder, keep adding to stack in the process
14 | while(curr) {
15 | s.push(curr);
16 | curr = curr->left;
17 | }
18 | }
19 |
20 | int next() { // explores right subT (if exists) of stack top node (inorder fashion)
21 | TreeNode* temp = s.top(); s.pop();
22 | helper(temp->right);
23 | return temp->val;
24 | }
25 |
26 | bool hasNext() {
27 | return !s.empty();
28 | }
29 | };
30 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 21 (BST)/Find pair with sum in BST.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | bool helper(TreeNode* root, unordered_set &s, int k){
6 | if(!root) return false;
7 | if(s.find(k-root->val) != s.end()) return true;
8 | s.insert(root->val);
9 | return helper(root->left, s, k) || helper(root->right, s, k);
10 | }
11 | bool findTarget(TreeNode* root, int k) {
12 | unordered_set s;
13 | return helper(root, s, k);
14 | }
15 | };
16 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 21 (BST)/Floor and ceil of BST.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | void helper(Node* root, int key, int& floor, int& ceil)
4 | {
5 |
6 | while (root) {
7 | // when the key itself is found, it is both the floor and ceil.
8 | if (root->data == key) {
9 | ceil = root->data;
10 | floor = root->data;
11 | return;
12 | }
13 | // if root < key, root is the floor (first smallest val) and ceil is somewhere in right subT
14 | if (key > root->data) {
15 | floor = root->data;
16 | root = root->right;
17 | }
18 | else { // converse
19 | ceil = root->data;
20 | root = root->left;
21 | }
22 | }
23 | return;
24 | }
25 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 21 (BST)/K-th largest element in BST.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | // return the Kth largest element in the given BST rooted at 'root'
4 | class Solution
5 | {
6 | public:
7 | int kLarge = 0, c = 0;
8 | void helper(Node *root, int K){
9 | if(!root || c >= K) return;
10 | // go right then left (reverse inorder)
11 | helper(root->right, K);
12 | c++;
13 | if(c == K){
14 | kLarge = root->data;
15 | return;
16 | }
17 | // now go left
18 | return helper(root->left, K);
19 | }
20 | int kthLargest(Node *root, int K)
21 | {
22 | helper(root, K);
23 | return kLarge;
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 21 (BST)/K-th smallest in BST.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution {
4 | public:
5 | int index = 1, kthSmall = 0;
6 | void inOrder(TreeNode* root, int k){
7 | if(!root) return;
8 | inOrder(root->left, k);
9 | // reach smallest ele on left most of tree
10 | if(index++ == k) {
11 | kthSmall = root->val; return;
12 | }
13 | inOrder(root->right, k);
14 | }
15 |
16 | int kthSmallest(TreeNode* root, int k) {
17 | inOrder(root, k);
18 | return kthSmall;
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 21 (BST)/Max sum BST in BT(Hard).cpp:
--------------------------------------------------------------------------------
1 | // Same logic as "Size of largest BST in BT". Instead of keeping track of sum in BSTNode, I keep track of no. of elements
2 |
3 | // Hari
4 |
5 | class Solution {
6 | public:
7 | // define a struct with parameters that keep check of whether BST exists
8 | // watch Tushar roy video on YT for explanation
9 | struct BSTNode {
10 | bool isBST;
11 | int min;
12 | int max;
13 | int sum;
14 | };
15 | BSTNode helper(TreeNode* curr, int &ans){
16 | if(curr){
17 | BSTNode left = helper(curr->left, ans);
18 | BSTNode right = helper(curr->right, ans);
19 | // for a node's isBST to be true, its left and right subT should
20 | // also be BSTs, and node's val > left's max and val > left.max && curr->val < right.min;
22 | // sum param of this particular node
23 | int sum = left.sum + right.sum + curr->val;
24 | // only if a BST can be formed at this curr will we modify ans
25 | if(isBST) ans = max(ans, sum);
26 | // return status to higher levels
27 | return {isBST, min(curr->val, left.min), max(curr->val, right.max), sum };
28 | } else return {true, INT_MAX, INT_MIN, 0};
29 | }
30 |
31 | int maxSumBST(TreeNode* root) {
32 | int ans = 0;
33 | helper(root, ans);
34 | return ans;
35 | }
36 | };
37 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 21 (BST)/Serialize and Deserialize(Hard).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Codec {
4 | public:
5 | // Watch Back to Back SWE's vid for explanation
6 | // Encodes a tree to a single string.
7 | string serialize(TreeNode* root) {
8 | if(!root) return "#"; // null nodes get converted to # in string
9 | return to_string(root->val) + "," + serialize(root->left) + "," + serialize(root->right); // preorder conversion to string separated by commas
10 | }
11 |
12 | // Decodes your encoded data to tree.
13 | TreeNode* deserialize(string data) {
14 | // take the string created in serialize and convert it back to BTree nodes
15 | if(data == "#") return nullptr;
16 | stringstream ss(data); // makes string operations easier. data is assigned to ss which is passed to helper function
17 | return desHelper(ss);
18 | }
19 |
20 | TreeNode* desHelper(stringstream &ss){
21 | string word;
22 | getline(ss,word,','); // each time we get a new element from stringstream to convert to node and add to BT. Delimiter is comma.
23 | if(word == "#") return nullptr;
24 | else {
25 | TreeNode* curr = new TreeNode(stoi(word));
26 | curr->left = desHelper(ss);
27 | curr->right = desHelper(ss);
28 | return curr;
29 | }
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 23 (Graphs)/BFS.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | // When there are no unconnected components in graph, no need to have an upper for loop for checking each vertex
4 |
5 | class Solution
6 | {
7 | public:
8 | //Function to return Breadth First Traversal of given graph.
9 | vectorbfsOfGraph(int V, vector adj[]){
10 | vector bfs;
11 | vector vis(V, 0);
12 | queue q;
13 | q.push(0);
14 | vis[0] = 1;
15 | while(!q.empty()) {
16 | int node = q.front();
17 | q.pop();
18 | bfs.push_back(node);
19 |
20 | for(auto it : adj[node]) {
21 | if(!vis[it]) {
22 | q.push(it);
23 | vis[it] = 1;
24 | }
25 | }
26 | }
27 |
28 | return bfs;
29 | }
30 | };
31 |
32 | // When there are some unconnected components in graph
33 |
34 | class Solution
35 | {
36 | public:
37 | //Function to return Breadth First Traversal of given graph.
38 | vectorbfsOfGraph(int V, vector adj[]){
39 | vector bfs;
40 | vector vis(V+1, 0);
41 |
42 | for(int i = 0; i q;
45 | q.push(i);
46 | vis[i] = 1;
47 |
48 | while(!q.empty()) {
49 | int node = q.front();
50 | q.pop();
51 | bfs.push_back(node);
52 |
53 | for(auto it : adj[node]) {
54 | if(!vis[it]) {
55 | q.push(it);
56 | vis[it] = 1;
57 | }
58 | }
59 | }
60 | }
61 | }
62 |
63 | return bfs;
64 | }
65 | };
66 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 23 (Graphs)/Bipartite Check(BFS).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution
4 | {
5 | public:
6 | bool cycleChk(int node, int parent, vectoradj[], vector &vis){
7 | // We use DFS this time. If a node is found to be already visited
8 | // and it is NOT the parent of our current node, then it has already been
9 | // traversed and hence is a cycle
10 | vis[node] = 1;
11 | for(auto it: adj[node]){
12 | if(!vis[it]){
13 | if(cycleChk(it, node, adj, vis)) return true;
14 | // as DFS keeps going down, if any iteration gives a True, return
15 | // true. No need to keep going down in DFS further
16 | } else {
17 | if(it != parent) return true;
18 | }
19 | }
20 | return false;
21 | }
22 | //Function to detect cycle in an undirected graph.
23 | bool isCycle(int V, vectoradj[])
24 | {
25 | vector vis(V+1,0);
26 | for(int i = 0; i adj[], int color[]){
7 | if(color[node] == -1) color[node] = 1;
8 | // Same logic as BFS. There we used Queue, here we just keep recursing
9 | // and exploring each node and constantly checking the color
10 | for(auto it: adj[node]){
11 | if(color[it] == -1){
12 | color[it] = 1 - color[node];
13 | if(!helper(it, adj, color)) return false;
14 | } else {
15 | if(color[it] == color[node]) return false;
16 | }
17 | }
18 | return true;
19 | }
20 |
21 |
22 | bool isBipartite(int V, vectoradj[]){
23 | int color[V]; // maintains color of nodes (0 or 1 are the available colors)
24 | memset(color, -1, sizeof(color)); // initial assignment
25 | for(int i = 0; i copies;
7 | Node* cloneGraph(Node* node) {
8 | // very simple implementation of a complex question
9 |
10 | // node points to the current node traversed in original graph
11 | if(!node) return nullptr; // base
12 |
13 | if(copies.find(node) == copies.end()) {
14 | // node not found in copied graph. Add it
15 | copies[node] = new Node(node->val, {});
16 |
17 | for(Node* it: node->neighbors){
18 | copies[node]->neighbors.push_back(cloneGraph(it));
19 | }
20 | }
21 | return copies[node];
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 23 (Graphs)/Cycle Detection Directed Graph (BFS)(Kahn).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | // We can use Kahn's algo (used in Topological Sort BFS) here. That algo works only
4 | // in DAG (directed acyclic (no cycle) graph). And topo sort is just linear ordering of
5 | // vertices. If vertex count doesn't match, then cycle exists in graph
6 |
7 | class Solution
8 | {
9 | public:
10 | //Function to detect cycle in a directed graph.
11 | bool isCyclic(int V, vector adj[])
12 | {
13 | queue q;
14 | vector indegree(V,0);
15 |
16 | // assign indegrees
17 | for(int i = 0; i res;
28 | while(!q.empty()){
29 | int curr = q.front(); q.pop();
30 | count++;
31 | res.push_back(curr);
32 | for(auto it: adj[curr]) {
33 | indegree[it]--;
34 | if(indegree[it] == 0) q.push(it);
35 | }
36 | }
37 |
38 | if(count == V) return false; // no cycle
39 | return true;
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 23 (Graphs)/Cycle Detection Directed Graph(DFS).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution
4 | {
5 | public:
6 | bool chkCycle(int node, vector adj[], int vis[], int dfsVis[]){
7 | vis[node] = 1; dfsVis[node] = 1;
8 | for(auto it: adj[node]) {
9 | // dfs
10 | if(!vis[it]){
11 | // not visited. Go to its child and then its child and so on.
12 | // If any 1 of the node is found to have cycle, then return
13 | // true through all recursions and then pass that true to isCyclic
14 | if(chkCycle(it, adj, vis, dfsVis)) return true;
15 | } else {
16 | // node is visited. If it is not visited in dfsVis then no probs,
17 | // as the node has been visited before but not on this traversal.
18 | if(dfsVis[it] == 1) return true;
19 | }
20 | }
21 | // after this node traversal is over and there are no more adj nodes for it, make its dfsVis 0. vis will NOT change
22 | dfsVis[node] = 0;
23 | return false; // pass this value higher recursive levels
24 | }
25 | //Function to detect cycle in a directed graph.
26 | bool isCyclic(int V, vector adj[])
27 | {
28 | // we have 2 arrays instead of 1 to keep track of visited.
29 | // vis is for all the nodes overall, and dfsVis is for
30 | // maintaining visited nodes in this current iteration only.
31 | int vis[V], dfsVis[V];
32 | memset(vis, 0, sizeof vis);
33 | memset(dfsVis, 0, sizeof dfsVis);
34 |
35 | for(int i = 0; iadj[], vector &vis){
7 | // We use BFS this time. If a node is found to be already visited
8 | // and it is NOT the parent of our current node, then it has already been
9 | // traversed and hence is a cycle
10 | queue> q;
11 | vis[node] = 1;
12 | q.push({node, -1}); // initial node won't have parent
13 |
14 | while(!q.empty()){
15 | int node = q.front(). first;
16 | int parent = q.front().second;
17 | q.pop();
18 |
19 | for(auto it: adj[node]){
20 | if(!vis[it]){
21 | vis[it] = 1;
22 | q.push({it, node});
23 | } else {
24 | // "it" node has been traversed already
25 | if(parent != it) return true;
26 | }
27 | }
28 | }
29 | return false;
30 | }
31 | //Function to detect cycle in an undirected graph.
32 | bool isCycle(int V, vectoradj[])
33 | {
34 | vector vis(V,0);
35 | for(int i = 0; iadj[], vector &vis){
7 | // We use DFS this time. If a node is found to be already visited
8 | // and it is NOT the parent of our current node, then it has already been
9 | // traversed and hence is a cycle
10 | vis[node] = 1;
11 | for(auto it: adj[node]){
12 | if(!vis[it]){
13 | if(cycleChk(it, node, adj, vis)) return true;
14 | // as DFS keeps going down, if any iteration gives a True, return
15 | // true. No need to keep going down in DFS further
16 | } else {
17 | if(it != parent) return true;
18 | }
19 | }
20 | return false;
21 | }
22 | //Function to detect cycle in an undirected graph.
23 | bool isCycle(int V, vectoradj[])
24 | {
25 | vector vis(V+1,0);
26 | for(int i = 0; i &res, vector &vis, vector adj[]) {
8 | // add this unvisited node to res
9 | res.push_back(node);
10 | vis[node] = 1;
11 | // recursively call its neighbor, which will call its neighbor and so on
12 | // once calls are over, they trace back and see if any other unvisited
13 | // neighbor is there for an already visited node
14 | for(auto it: adj[node]){
15 | if(!vis[it]) helper(it, res, vis, adj);
16 | }
17 | }
18 | //Function to return a list containing the DFS traversal of the graph.
19 | vectordfsOfGraph(int V, vector adj[])
20 | {
21 | vector res;
22 | vector vis(V,0);
23 | for(int i = 0; iv edge exists in graph, in topo sort order u comes before v. Kahn's algo always starts from a vertex w indegree 0. As nodes are added to final ans,
7 | // their adj node's dependency factor dec. by 1 and hence we subtract.
8 |
9 | class Solution
10 | {
11 | public:
12 | //Function to return list containing vertices in Topological order.
13 | vector topoSort(int V, vector adj[])
14 | {
15 | queue q;
16 | vector indegree(V,0);
17 | // add indegree values for all node
18 | for(int i = 0; iit is edge so it's indegree += 1
20 | }
21 |
22 | // whichever nodes have 0 indegree, add them to Q
23 | for(int i = 0; i res;
29 | while(!q.empty()){
30 | int curr = q.front(); q.pop();
31 | res.push_back(curr);
32 |
33 | for(auto it: adj[curr]){
34 | indegree[it]--;
35 | if(indegree[it] == 0) q.push(it);
36 | }
37 | }
38 |
39 | return res;
40 | }
41 | };
42 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 23 (Graphs)/Topological Sort(DFS).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | class Solution
4 | {
5 | public:
6 | void helper(int node, vector &vis, stack &s, vector adj[]){
7 | vis[node] = 1;
8 |
9 | for(auto it: adj[node]){
10 | if(!vis[it])
11 | helper(it, vis, s, adj);
12 | }
13 | s.push(node);
14 | }
15 | //Function to return list containing vertices in Topological order.
16 | vector topoSort(int V, vector adj[])
17 | {
18 | stack s;
19 | // after traversing a node when there is not adj node left, add that node into
20 | // stack. So always child is added first and then parent. So whe popping out
21 | // from stack, parent comes before child in topologicl sort sequence
22 | vector vis(V,0);
23 | for(int i = 0; i res;
28 | while(!s.empty()){
29 | res.push_back(s.top()); s.pop();
30 | }
31 | return res;
32 | }
33 | };
34 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 24 (Graphs)/Bellman Ford's Algo.cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | int isNegativeWeightCycle(int n, vector>edges){
4 | // edges[i][0,1,2] = u,v, weight respectively
5 | // get dist array
6 | int INF = 1e9+7;
7 | vector dist(n, INF);
8 | dist[0] = 0; //source
9 |
10 | for(int i = 1; i<=n-1; i++){ // relaxation for n-1 times
11 | for(auto it: edges){
12 | if(dist[it[0]] + it[2] < dist[it[1]]){
13 | dist[it[1]] = dist[it[0]] + it[2];
14 | }
15 | }
16 | }
17 |
18 | // try relaxing once more. If any dist val changes then -ve cycle exists
19 | int res = 0;
20 | for(auto it: edges){
21 | if(dist[it[0]] + it[2] < dist[it[1]]){
22 | res = 1;
23 | return res;
24 | }
25 | }
26 |
27 | return res;
28 | };
29 |
--------------------------------------------------------------------------------
/Striver SDE Sheet/Day - 24 (Graphs)/Bridges in Graph (VHard).cpp:
--------------------------------------------------------------------------------
1 | // Hari
2 |
3 | #include
4 | using namespace std;
5 |
6 | // Bridges are edges that if you remove them, the graph breaks. We will do DFS here to find # of bridges
7 | // We use 2 arrays tin[] (time of insertion) and low[] (smallest time in adj nodes of curr)
8 | // Once dfs(it) trav is finished, we try to update its low[] and then check condition low[it] > tin[node]
9 | // If condt true, then that edge is a bridge.
10 | // low[node] is either time of insertion (assigned at start) or lowest time of insertion across adj nodes
11 | void dfs(int node, int parent, vector &vis, vector &tin, vector &low, int &timer, vector adj[]){
12 | vis[node] = 1;
13 | tin[node] = low[node] = timer++; // first dfs traversal both arrays get same val
14 |
15 | for(auto it: adj[node]){
16 | if(it == parent) continue; // dont want to go back in dfs. We want forward progress
17 |
18 | if(!vis[it]){
19 | dfs(it, node, vis, tin, low, timer, adj);
20 | // after dfs calls over, we update low
21 | low[node] = min(low[node], low[it]);
22 |
23 | // bridges condition check - if low[it] is lesser, then the other way (not edge removed) can reach node easier.
24 | if(low[it] > tin[node]) cout << node << "--" << it << "is a bridge" << endl;
25 | } else {
26 | // already visited. Just update low. Bridge cant exist as its already visited without
27 | // going thru bridge
28 | low[node] = min(low[node], tin[it]);
29 | }
30 |
31 | }
32 | }
33 |
34 |
35 |
36 | int main() {
37 | int N, m;
38 | cin >> N >> m;
39 | vector adj[N];
40 | // creating the graph from user input
41 | for(int i = 0; i> u >> v;
44 | adj[u].push_back(v);
45 | adj[v].push_back(u);
46 | }
47 |
48 | vector tin(N, -1);
49 | vector low(N, -1);
50 | vector