├── .gitignore ├── DP ├── boolparmem.py ├── boolparrecu.py ├── coinchangemaxways.py ├── coinchangemincoins.py ├── countsubdiff.py ├── countsubsum.py ├── diabtree.py ├── eggdropmem.py ├── eggdropmemopt.py ├── eggdroprec.py ├── equalsumpart.py ├── knapsack_mem.py ├── knapsack_rec.py ├── knapsack_top_down.py ├── longestcomsubseq.py ├── longestcomsubstr.py ├── longestrepsubseq.py ├── longpalsubseq.py ├── maxpathsum1.py ├── maxpathsum2.py ├── mcmmemoized.py ├── mcmrecursive.py ├── mindelpal.py ├── mininsdel.py ├── mininspal.py ├── minsubdif.py ├── palpartmem.py ├── palpartmemopt.py ├── palpartrec.py ├── plongestcomsubseq.py ├── pshortestcomsupseq.py ├── rodcut.py ├── scrambledmem.py ├── scrambledrec.py ├── seqpatternmat.py ├── shortestcomsupseq.py ├── subsetsum.py └── targetsum.py ├── DSA 450 └── Arrays │ ├── 10minjumps.py │ ├── 11dupar.py │ ├── 12merarr.py │ ├── 14merint.py │ ├── 15nextperm.py │ ├── 16invcount.py │ ├── 17stocksell.py │ ├── 18countpairs.py │ ├── 19commonnum.py │ ├── 1revarray.py │ ├── 20altnegpos.py │ ├── 21sub0.py │ ├── 22factorial.py │ ├── 23maxprod.py │ ├── 24consub.py │ ├── 25nbykocc.py │ ├── 26maxprofit.py │ ├── 27subarr.py │ ├── 28tripletsum.py │ ├── 29rainwater.py │ ├── 2maxmin.py │ ├── 30chocdis.py │ ├── 35mediansamesize.py │ ├── 3kmaxmin.py │ ├── 4sort012.py │ ├── 5negele.py │ ├── 6arruni.py │ ├── 7clockrev.py │ ├── 8maxsubsum.py │ └── 9mindis.py ├── DSA-Python ├── CirularSingleLinkedList ├── binary_search.py ├── binary_search_tree.py ├── bubble_sort.py ├── doubly_linked_list.py ├── graph.py ├── hash_maps.py ├── insertion_sort.py ├── linked_list.py ├── merge_sort.py ├── queue.py ├── quick_sort.py ├── selection_sort.py ├── shell_sort.py ├── stack.py ├── tree.py └── util.py ├── DSA_Header.png ├── README.md ├── Recursion ├── basic1.py ├── basic2.py ├── basic3.py ├── basic4.py ├── hard1.py ├── hard2.py ├── medium1.py ├── medium2.py ├── medium3.py ├── medium4.py ├── medium5.py ├── medium6.py ├── medium7.py └── minion.py ├── Stack ├── 10_minelexsp.py ├── 11_minelspopt.py ├── 2_nextgrtright.py ├── 3_nextgrtleft.py ├── 4_nearsmlleft.py ├── 5_nearsmlright.py ├── 6_stockspan.py ├── 7_maxarhist.py ├── 8_maxarbinmatrix.py └── 9_rainwatertrap.py └── Striver Sheet ├── Arrays ├── 10_countinv.py ├── 11_stockbuysell.py ├── 12_rotatemat.py ├── 13_ser2dmat.py ├── 14_powxn.py ├── 15_majelnb2.py ├── 16_majelnb3.py ├── 17_unipath.py ├── 18_revpairs.py ├── 1_012sort.py ├── 2_missrep.py ├── 3_mergerarr.py ├── 4_kadane.py ├── 5_mergint.py ├── 6_dupinarr.py ├── 7_matrixzero.py ├── 8_pascaltri.py └── 9_nextpermu.py └── Hashing ├── 1_twosum.py ├── 2_foursum.py ├── 3_longconseq.py ├── 4_largesubzero.py ├── 5_cntsubxork.py └── 6_lonsubstrep.py /.gitignore: -------------------------------------------------------------------------------- 1 | codechef1.py 2 | codechef2.py 3 | codechef3.py 4 | codechef4.py 5 | leetcode.py 6 | DSA_Images -------------------------------------------------------------------------------- /DP/boolparmem.py: -------------------------------------------------------------------------------- 1 | # Evaluate Expression to True Boolean Parenthesization Recursive 2 | # https://practice.geeksforgeeks.org/problems/boolean-parenthesization5610/1 3 | # https://www.interviewbit.com/problems/evaluate-expression-to-true/ 4 | 5 | st = "T^F|F" 6 | s = list(st) 7 | 8 | dp = {} 9 | 10 | def solve(s, i, j, isTrue): 11 | if(i > j): 12 | return 1 13 | 14 | if(i == j): 15 | if(isTrue): 16 | return int(s[i]=="T") 17 | else: 18 | return int(s[i]=="F") 19 | 20 | st_tmp = str(i) + " " + str(j) + " " + str(int(isTrue)) 21 | if st_tmp in dp: 22 | return dp[st_tmp] 23 | 24 | ans = 0 25 | 26 | for k in range(i+1, j, 2): 27 | lt_st_tmp = str(i) + " " + str(k-1) + " " + str(True) 28 | lf_st_tmp = str(i) + " " + str(k-1) + " " + str(False) 29 | rt_st_tmp = str(k+1) + " " + str(j) + " " + str(True) 30 | rf_st_tmp = str(k+1) + " " + str(j) + " " + str(False) 31 | 32 | if lt_st_tmp in dp: 33 | lt = dp[lt_st_tmp] 34 | else: 35 | lt = solve(s, i, k-1, True)%1003 36 | 37 | if lf_st_tmp in dp: 38 | lf = dp[lf_st_tmp] 39 | else: 40 | lf = solve(s, i, k-1, False)%1003 41 | 42 | if rt_st_tmp in dp: 43 | rt = dp[rt_st_tmp] 44 | else: 45 | rt = solve(s, k+1, j, True)%1003 46 | 47 | if rf_st_tmp in dp: 48 | rf = dp[rf_st_tmp] 49 | else: 50 | rf = solve(s, k+1, j, False)%1003 51 | 52 | if(s[k]=="&"): 53 | if(isTrue==True): 54 | ans += lt*rt 55 | else: 56 | ans += lt*rf + lf*rt + lf*rf 57 | elif(s[k]=="|"): 58 | if(isTrue==True): 59 | ans += lt*rf + lf*rt + lt*rt 60 | else: 61 | ans += lf*rf 62 | elif(s[k]=="^"): 63 | if(isTrue==True): 64 | ans += lt*rf + lf*rt 65 | else: 66 | ans += lf*rf + lt*rt 67 | ans = ans%1003 68 | dp[st_tmp] = ans%1003 69 | return ans 70 | 71 | print(solve(s, 0, len(s)-1, True)) -------------------------------------------------------------------------------- /DP/boolparrecu.py: -------------------------------------------------------------------------------- 1 | # Evaluate Expression to True Boolean Parenthesization Recursive 2 | # https://practice.geeksforgeeks.org/problems/boolean-parenthesization5610/1 3 | 4 | st = "T|F&T" 5 | s = list(st) 6 | 7 | def solve(s, i, j, isTrue): 8 | if(i > j): 9 | return 1 10 | 11 | if(i == j): 12 | if(isTrue): 13 | return int(s[i]=="T") 14 | else: 15 | return int(s[i]=="F") 16 | 17 | ans = 0 18 | 19 | for k in range(i+1, j, 2): 20 | lt = solve(s, i, k-1, True)%1003 21 | lf = solve(s, i, k-1, False)%1003 22 | rt = solve(s, k+1, j, True)%1003 23 | rf = solve(s, k+1, j, False)%1003 24 | 25 | if(s[k]=="&"): 26 | if(isTrue==True): 27 | ans += lt*rt 28 | else: 29 | ans += lt*rf + lf*rt + lf*rf 30 | elif(s[k]=="|"): 31 | if(isTrue==True): 32 | ans += lt*rf + lf*rt + lt*rt 33 | else: 34 | ans += lf*rf 35 | elif(s[k]=="^"): 36 | if(isTrue==True): 37 | ans += lt*rf + lf*rt 38 | else: 39 | ans += lf*rf + lt*rt 40 | ans = ans%1003 41 | return ans 42 | 43 | print(solve(s, 0, len(s)-1, True)) -------------------------------------------------------------------------------- /DP/coinchangemaxways.py: -------------------------------------------------------------------------------- 1 | # Coin Change Maximum Ways 2 | # https://www.geeksforgeeks.org/coin-change-dp-7/ 3 | # https://leetcode.com/problems/coin-change-2/ 4 | 5 | coins = [1,2,3] 6 | n = len(coins) 7 | sm = 5 8 | 9 | dp = [] 10 | 11 | for i in range(n+1): 12 | a = [] 13 | for j in range(sm+1): 14 | if(j==0): 15 | a.append(1) 16 | elif(i==0): 17 | a.append(0) 18 | else: 19 | if(coins[i-1]<=j): 20 | a.append(a[j-coins[i-1]] + dp[i-1][j]) 21 | else: 22 | a.append(dp[i-1][j]) 23 | dp.append(a) 24 | 25 | #print(dp) 26 | print(dp[n][sm]) -------------------------------------------------------------------------------- /DP/coinchangemincoins.py: -------------------------------------------------------------------------------- 1 | # Coin Change Minimum Coins 2 | # https://www.geeksforgeeks.org/find-minimum-number-of-coins-that-make-a-change/ 3 | # https://leetcode.com/problems/coin-change/ 4 | 5 | import sys 6 | coins = [1,2,3] 7 | n = len(coins) 8 | sm = 5 9 | 10 | dp = [] 11 | 12 | for i in range(n+1): 13 | a = [] 14 | for j in range(sm+1): 15 | if(i==0): 16 | a.append(sys.maxsize - 1) 17 | elif(j==0): 18 | a.append(0) 19 | elif(i==1): 20 | if(j%coins[0]==0): 21 | a.append(j//coins[0]) 22 | else: 23 | a.append(sys.maxsize-1) 24 | else: 25 | if(coins[i-1]<=j): 26 | a.append(min(1 + a[j-coins[i-1]], dp[i-1][j])) 27 | else: 28 | a.append(dp[i-1][j]) 29 | dp.append(a) 30 | 31 | print(dp[n][sm]) -------------------------------------------------------------------------------- /DP/countsubdiff.py: -------------------------------------------------------------------------------- 1 | # Count number of Subset with given Difference 2 | 3 | arr = [1, 1, 2, 3] 4 | df = 1 5 | n = len(arr) 6 | def subsetdiff(arr, n, df): 7 | sm = (df+sum(arr))/2 8 | if(sm == int(sm)): 9 | sm = int(sm) 10 | else: 11 | return 0 12 | 13 | dp = [] 14 | for i in range(n+1): 15 | a = [] 16 | for j in range(sm+1): 17 | if(i==0 and j==0): 18 | a.append(1) 19 | elif(i==0): 20 | a.append(0) 21 | elif(j==0): 22 | a.append(1) 23 | else: 24 | if(arr[i-1]<=j): 25 | a.append(dp[i-1][j-arr[i-1]] + dp[i-1][j]) 26 | else: 27 | a.append(dp[i-1][j]) 28 | dp.append(a) 29 | 30 | return dp[n][sm] 31 | 32 | print(subsetdiff(arr, n, df)) -------------------------------------------------------------------------------- /DP/countsubsum.py: -------------------------------------------------------------------------------- 1 | # Count of Subset Sum 2 | # https://www.geeksforgeeks.org/count-of-subsets-with-sum-equal-to-x/ 3 | 4 | arr = [2, 3, 5, 6, 8, 10] 5 | sm = 10 6 | n = len(arr) 7 | 8 | dp = [] 9 | for i in range(n+1): 10 | a = [] 11 | for j in range(sm+1): 12 | if(i==0 and j==0): 13 | a.append(1) 14 | elif(i==0): 15 | a.append(0) 16 | elif(j==0): 17 | a.append(1) 18 | else: 19 | if(arr[i-1]<=j): 20 | a.append(dp[i-1][j-arr[i-1]] + dp[i-1][j]) 21 | else: 22 | a.append(dp[i-1][j]) 23 | dp.append(a) 24 | 25 | print(dp[n][sm]) -------------------------------------------------------------------------------- /DP/diabtree.py: -------------------------------------------------------------------------------- 1 | # Diameter of a Binary Tree 2 | # https://practice.geeksforgeeks.org/problems/diameter-of-binary-tree/1 3 | # https://leetcode.com/problems/diameter-of-binary-tree/submissions/ 4 | 5 | import sys 6 | 7 | def solve(root, res): 8 | if(root == None): 9 | return 0 10 | 11 | l = solve(root.left, res) 12 | r = solve(root.right, res) 13 | 14 | tmp = max(l, r) + 1 15 | # ans = max(tmp, 1+l+r) not required 16 | # res[0] = max(res[0], ans) 17 | res[0] = max(res[0], 1+l+r) 18 | 19 | return tmp 20 | 21 | root = "some tree" 22 | 23 | res = [-sys.maxsize - 1] 24 | 25 | ans = solve(root, res) 26 | 27 | print(res[0]) -------------------------------------------------------------------------------- /DP/eggdropmem.py: -------------------------------------------------------------------------------- 1 | # Egg Dropping Problem Memoization 2 | # https://practice.geeksforgeeks.org/problems/egg-dropping-puzzle/0 3 | # https://leetcode.com/problems/super-egg-drop/ 4 | 5 | import sys 6 | 7 | e = 3 8 | f = 5 9 | 10 | dp = [[-1]*(f+1) for _ in range(e+1)] 11 | 12 | def solve(e, f): 13 | if(e == 1): 14 | return f 15 | 16 | if(f == 0 or f == 1): 17 | return f 18 | 19 | if(dp[e][f] != -1): 20 | return dp[e][f] 21 | else: 22 | mn = sys.maxsize 23 | 24 | for i in range(1, f+1): 25 | temp = 1 + max(solve(e-1, i-1), solve(e, f-i)) 26 | mn = min(mn, temp) 27 | 28 | dp[e][f] = mn 29 | return mn 30 | 31 | print(solve(e, f)) -------------------------------------------------------------------------------- /DP/eggdropmemopt.py: -------------------------------------------------------------------------------- 1 | # Egg Dropping Problem Memoization Optimized 2 | # https://practice.geeksforgeeks.org/problems/egg-dropping-puzzle/0 3 | # https://leetcode.com/problems/super-egg-drop/ 4 | 5 | # Gives TLE for Python code on Leetcode and GFG but runs with Java code on GFG but not Leetcode 6 | 7 | import sys 8 | 9 | e = 3 10 | f = 5 11 | 12 | dp = [[-1]*(f+1) for _ in range(e+1)] 13 | 14 | def solve(e, f): 15 | if(e == 1): 16 | return f 17 | 18 | if(f == 0 or f == 1): 19 | return f 20 | 21 | if(dp[e][f] != -1): 22 | return dp[e][f] 23 | else: 24 | mn = sys.maxsize 25 | 26 | for i in range(1, f+1): 27 | # for broken scenario 28 | if(dp[e-1][i-1] != -1): 29 | broken = dp[e-1][i-1] 30 | else: 31 | broken = solve(e-1, i-1) 32 | dp[e-1][i-1] = broken 33 | 34 | # for not broken scenario 35 | if(dp[e][f-i] != -1): 36 | n_broken = dp[e][f-i] 37 | else: 38 | n_broken = solve(e, f-i) 39 | dp[e][f-i] = n_broken 40 | 41 | temp = 1 + max(broken, n_broken) 42 | mn = min(mn, temp) 43 | 44 | dp[e][f] = mn 45 | return mn 46 | 47 | print(solve(e, f)) -------------------------------------------------------------------------------- /DP/eggdroprec.py: -------------------------------------------------------------------------------- 1 | # Egg Dropping Problem Recursive 2 | # https://practice.geeksforgeeks.org/problems/egg-dropping-puzzle/0 3 | # https://leetcode.com/problems/super-egg-drop/ 4 | 5 | import sys 6 | 7 | e = 3 8 | f = 5 9 | 10 | def solve(e, f): 11 | if(e == 1): 12 | return f 13 | 14 | if(f == 0 or f == 1): 15 | return f 16 | 17 | mn = sys.maxsize 18 | 19 | for i in range(1, f+1): 20 | temp = 1 + max(solve(e-1, i-1), solve(e, f-i)) 21 | mn = min(mn, temp) 22 | 23 | return mn 24 | 25 | print(solve(e, f)) -------------------------------------------------------------------------------- /DP/equalsumpart.py: -------------------------------------------------------------------------------- 1 | # Equal Sum Partition 2 | # https://leetcode.com/problems/partition-equal-subset-sum/ 3 | 4 | arr = [1, 5, 11, 5] 5 | 6 | def canPartition(nums): 7 | if(sum(nums)%2!=0): 8 | return False 9 | n = len(nums) 10 | sm = sum(nums)//2 11 | dp = [] 12 | for i in range(n+1): 13 | a = [] 14 | for j in range(sm+1): 15 | if(i==0 and j==0): 16 | a.append(True) 17 | if(i==0): 18 | a.append(False) 19 | elif(j==0): 20 | a.append(True) 21 | else: 22 | if(nums[i-1]<=j): 23 | a.append(dp[i-1][j-nums[i-1]] or dp[i-1][j]) 24 | else: 25 | a.append(dp[i-1][j]) 26 | dp.append(a) 27 | return dp[n][sm] 28 | 29 | print(canPartition(arr)) -------------------------------------------------------------------------------- /DP/knapsack_mem.py: -------------------------------------------------------------------------------- 1 | # 0-1 Knapsack Memoization 2 | 3 | wt = [1,3,4,5] 4 | val = [1,4,5,7] 5 | w = 7 6 | n = len(wt) 7 | 8 | dp = [] 9 | for i in range(w+1): 10 | a = [] 11 | for j in range(n+1): 12 | a.append(-1) 13 | dp.append(a) 14 | 15 | def knapsack(wt, val, w, n, dp): 16 | if(n == 0 or w == 0): 17 | return 0 18 | if(dp[w][n]!=-1): 19 | return dp[w][n] 20 | if(wt[n-1]<=w): 21 | dp[w][n] = max(val[n-1] + knapsack(wt, val, w-wt[n-1], n-1, dp), knapsack(wt, val, w, n-1, dp)) 22 | return dp[w][n] 23 | else: 24 | dp[w][n] = knapsack(wt, val, w, n-1, dp) 25 | return dp[w][n] 26 | 27 | print(knapsack(wt, val, w, n, dp)) -------------------------------------------------------------------------------- /DP/knapsack_rec.py: -------------------------------------------------------------------------------- 1 | # 0-1 Knapsack Recursive 2 | 3 | def knapsack(wt, val, w, n): 4 | if(n == 0 or w == 0): 5 | return 0 6 | 7 | if(wt[n-1]<=w): 8 | return max(val[n-1] + knapsack(wt, val, w-wt[n-1], n-1), knapsack(wt, val, w, n-1)) 9 | else: 10 | return knapsack(wt, val, w, n-1) 11 | wt = [1,3,4,5] 12 | val = [1,4,5,7] 13 | w = 7 14 | n = len(wt) 15 | 16 | print(knapsack(wt, val, w, n)) -------------------------------------------------------------------------------- /DP/knapsack_top_down.py: -------------------------------------------------------------------------------- 1 | # 0-1 Knapsack Top-Down 2 | 3 | wt = [1,3,4,5] 4 | val = [1,4,5,7] 5 | w = 7 6 | n = len(wt) 7 | 8 | dp = [] 9 | for i in range(n+1): 10 | a = [] 11 | for j in range(w+1): 12 | if(i==0 or j==0): 13 | a.append(0) 14 | else: 15 | if(wt[i-1]<=j): 16 | a.append(max(val[i-1] + dp[i-1][j-wt[i-1]], dp[i-1][j])) 17 | else: 18 | a.append(dp[i-1][j]) 19 | dp.append(a) 20 | 21 | """for i in range(1, n+1): 22 | for j in range(1, w+1): 23 | if(wt[i-1]<=j): 24 | dp[i][j] = max(val[i-1] + dp[i-1][j-wt[i-1]], dp[i-1][j]) 25 | else: 26 | dp[i][j] = dp[i-1][j]""" 27 | 28 | #print(dp) 29 | print(dp[n][w]) -------------------------------------------------------------------------------- /DP/longestcomsubseq.py: -------------------------------------------------------------------------------- 1 | # Longest Common Subsequence Top Down 2 | # https://www.geeksforgeeks.org/longest-common-subsequence-dp-4/ 3 | # https://leetcode.com/problems/longest-common-subsequence/ 4 | 5 | x = "abcdaf" 6 | y = "acbcf" 7 | n = len(x) 8 | m = len(y) 9 | 10 | dp = [] 11 | 12 | for i in range(n+1): 13 | a = [] 14 | for j in range(m+1): 15 | if(i==0 or j==0): 16 | a.append(0) 17 | else: 18 | if(x[i-1] == y[j-1]): 19 | a.append(1 + dp[i-1][j-1]) 20 | else: 21 | a.append(max(dp[i-1][j], a[j-1])) 22 | dp.append(a) 23 | 24 | print(dp[n][m]) -------------------------------------------------------------------------------- /DP/longestcomsubstr.py: -------------------------------------------------------------------------------- 1 | # Longest Common Substring 2 | # https://www.geeksforgeeks.org/longest-common-substring-dp-29/ 3 | # https://leetcode.com/problems/maximum-length-of-repeated-subarray/ (Similar but with number array) 4 | 5 | x = "abcdaf" 6 | y = "acbcf" 7 | #x = "abcijkl" 8 | #y = "ijklabc" 9 | n = len(x) 10 | m = len(y) 11 | 12 | dp = [] 13 | mx = 0 14 | for i in range(n+1): 15 | a = [] 16 | for j in range(m+1): 17 | if(i==0 or j==0): 18 | a.append(0) 19 | else: 20 | if(x[i-1] == y[j-1]): 21 | tmp = 1 + dp[i-1][j-1] 22 | a.append(tmp) 23 | mx = max(mx, tmp) 24 | else: 25 | a.append(0) 26 | dp.append(a) 27 | 28 | #print(dp) 29 | print(mx) -------------------------------------------------------------------------------- /DP/longestrepsubseq.py: -------------------------------------------------------------------------------- 1 | # Longest repeating subsequence 2 | # https://practice.geeksforgeeks.org/problems/longest-repeating-subsequence2004/1 3 | 4 | x = "aabebcdd" 5 | n = len(x) 6 | m = len(x) 7 | 8 | dp = [] 9 | 10 | for i in range(n+1): 11 | a = [] 12 | for j in range(m+1): 13 | if(i==0 or j==0): 14 | a.append(0) 15 | else: 16 | if(x[i-1] == x[j-1] and i != j): 17 | a.append(1 + dp[i-1][j-1]) 18 | else: 19 | a.append(max(dp[i-1][j], a[j-1])) 20 | dp.append(a) 21 | 22 | print(dp[n][m]) -------------------------------------------------------------------------------- /DP/longpalsubseq.py: -------------------------------------------------------------------------------- 1 | # Longest Palindromic Subsequence 2 | # https://www.geeksforgeeks.org/longest-palindromic-subsequence-dp-12/ 3 | 4 | x = "agbcba" 5 | y = x[::-1] 6 | n = len(x) 7 | m = len(y) 8 | 9 | dp = [] 10 | 11 | for i in range(n+1): 12 | a = [] 13 | for j in range(m+1): 14 | if(i==0 or j==0): 15 | a.append(0) 16 | else: 17 | if(x[i-1] == y[j-1]): 18 | a.append(1 + dp[i-1][j-1]) 19 | else: 20 | a.append(max(dp[i-1][j], a[j-1])) 21 | dp.append(a) 22 | 23 | print(dp[n][m]) -------------------------------------------------------------------------------- /DP/maxpathsum1.py: -------------------------------------------------------------------------------- 1 | # Maximum Path Sum | From any node to any node 2 | # https://www.geeksforgeeks.org/find-maximum-path-sum-in-a-binary-tree/ 3 | # https://leetcode.com/problems/binary-tree-maximum-path-sum/ 4 | 5 | import sys 6 | 7 | def solve(root, res): 8 | if(root == None): 9 | return 0 10 | 11 | l = solve(root.left, res) 12 | r = solve(root.right, res) 13 | 14 | tmp = max(max(l, r) + root.val, root.val) 15 | ans = max(tmp, l + r + root.val) 16 | res[0] = max(res[0], ans) 17 | 18 | return tmp 19 | 20 | root = "some tree" 21 | 22 | res = [-sys.maxsize - 1] 23 | 24 | ans = solve(root, res) 25 | 26 | if(res[0]==(-sys.maxsize - 1)): 27 | print(ans) 28 | 29 | print(res[0]) -------------------------------------------------------------------------------- /DP/maxpathsum2.py: -------------------------------------------------------------------------------- 1 | # Maximum Path Sum | From leaf node to leaf node 2 | # https://practice.geeksforgeeks.org/problems/maximum-path-sum/1 3 | 4 | import sys 5 | 6 | def solve(root, res): 7 | if(root == None): 8 | return 0 9 | 10 | l = solve(root.left, res) 11 | r = solve(root.right, res) 12 | 13 | if(root.left != None and root.right != None): 14 | tmp = max(l, r) + root.val 15 | res[0] = max(res[0], l + r + root.val) 16 | return tmp 17 | 18 | if(root.left == None): 19 | return r + root.val 20 | elif(root.right == None): 21 | return l + root.val 22 | 23 | root = "some tree" 24 | 25 | res = [-sys.maxsize - 1] 26 | 27 | ans = solve(root, res) 28 | 29 | print(res[0]) -------------------------------------------------------------------------------- /DP/mcmmemoized.py: -------------------------------------------------------------------------------- 1 | # Matrix chain multiplication Memoization 2 | # https://practice.geeksforgeeks.org/problems/matrix-chain-multiplication0303/1 3 | import sys 4 | arr = [40, 20, 30, 10, 30] 5 | 6 | dp = [[-1 for i in range(len(arr))] for j in range(len(arr))] 7 | 8 | def solve(arr, i, j): 9 | if(i==j): 10 | return 0 11 | 12 | if(dp[i][j] != -1): 13 | return dp[i][j] 14 | 15 | mn = sys.maxsize 16 | 17 | for k in range(i, j): 18 | temp = solve(arr, i, k) + solve(arr, k+1, j) + (arr[i-1] * arr[k] * arr[j]) 19 | mn = min(temp, mn) 20 | 21 | dp[i][j] = mn 22 | return mn 23 | 24 | print(solve(arr, 1, len(arr)-1)) -------------------------------------------------------------------------------- /DP/mcmrecursive.py: -------------------------------------------------------------------------------- 1 | # Matrix Chain Multiplication Recursive 2 | # https://practice.geeksforgeeks.org/problems/matrix-chain-multiplication0303/1 3 | 4 | arr = [40, 20, 30, 10, 30] 5 | 6 | def solve(arr, i, j): 7 | if(i>=j): 8 | return 0 9 | 10 | mn = 999999999 11 | 12 | for k in range(i, j): 13 | temp = solve(arr, i, k) + solve(arr, k+1, j) + (arr[i-1] * arr[k] * arr[j]) 14 | 15 | mn = min(temp, mn) 16 | 17 | return mn 18 | 19 | print(solve(arr, 1, len(arr)-1)) -------------------------------------------------------------------------------- /DP/mindelpal.py: -------------------------------------------------------------------------------- 1 | # Minimum number of deletion in a string to make it a palindrome 2 | # https://practice.geeksforgeeks.org/problems/minimum-deletitions1648/1 3 | 4 | 5 | x = "agbcba" 6 | y = x[::-1] 7 | n = len(x) 8 | m = len(y) 9 | 10 | dp = [] 11 | 12 | for i in range(n+1): 13 | a = [] 14 | for j in range(m+1): 15 | if(i==0 or j==0): 16 | a.append(0) 17 | else: 18 | if(x[i-1] == y[j-1]): 19 | a.append(1 + dp[i-1][j-1]) 20 | else: 21 | a.append(max(dp[i-1][j], a[j-1])) 22 | dp.append(a) 23 | 24 | print(n - dp[n][m]) -------------------------------------------------------------------------------- /DP/mininsdel.py: -------------------------------------------------------------------------------- 1 | # Minimum Number of Insertion and Deletion to convert String a to String b 2 | # https://practice.geeksforgeeks.org/problems/minimum-number-of-deletions-and-insertions0209/1# 3 | # https://leetcode.com/problems/delete-operation-for-two-strings/ 4 | 5 | x = "heap" 6 | y = "pea" 7 | n = len(x) 8 | m = len(y) 9 | 10 | dp = [] 11 | 12 | for i in range(n+1): 13 | a = [] 14 | for j in range(m+1): 15 | if(i==0 or j==0): 16 | a.append(0) 17 | else: 18 | if(x[i-1] == y[j-1]): 19 | a.append(1 + dp[i-1][j-1]) 20 | else: 21 | a.append(max(dp[i-1][j], a[j-1])) 22 | dp.append(a) 23 | 24 | print("Inserted: " + str(m - dp[n][m]) + ", Deleted: " + str(n - dp[n][m])) -------------------------------------------------------------------------------- /DP/mininspal.py: -------------------------------------------------------------------------------- 1 | # Minimum number of insertion in a string to make it a palindrome (same as deletion) 2 | # https://practice.geeksforgeeks.org/problems/form-a-palindrome1455/1# 3 | 4 | 5 | x = "aebcbda" 6 | y = x[::-1] 7 | n = len(x) 8 | m = len(y) 9 | 10 | dp = [] 11 | 12 | for i in range(n+1): 13 | a = [] 14 | for j in range(m+1): 15 | if(i==0 or j==0): 16 | a.append(0) 17 | else: 18 | if(x[i-1] == y[j-1]): 19 | a.append(1 + dp[i-1][j-1]) 20 | else: 21 | a.append(max(dp[i-1][j], a[j-1])) 22 | dp.append(a) 23 | 24 | print(n - dp[n][m]) -------------------------------------------------------------------------------- /DP/minsubdif.py: -------------------------------------------------------------------------------- 1 | # Minimum Subset Sum Difference 2 | # https://www.geeksforgeeks.org/partition-a-set-into-two-subsets-such-that-the-difference-of-subset-sums-is-minimum/ 3 | 4 | arr = [1, 2, 7] 5 | sm = sum(arr) 6 | n = len(arr) 7 | 8 | dp = [] 9 | for i in range(n+1): 10 | a = [] 11 | for j in range(sm+1): 12 | if(i==0 and j==0): 13 | a.append(True) 14 | elif(i==0): 15 | a.append(False) 16 | elif(j==0): 17 | a.append(True) 18 | else: 19 | if(arr[i-1]<=j): 20 | a.append(dp[i-1][j-arr[i-1]] or dp[i-1][j]) 21 | else: 22 | a.append(dp[i-1][j]) 23 | dp.append(a) 24 | 25 | mn = 99999999 26 | 27 | for i in range(sm//2): 28 | if(dp[-1][i] == True): 29 | mn = min(sm-2*i, mn) 30 | 31 | print(mn) -------------------------------------------------------------------------------- /DP/palpartmem.py: -------------------------------------------------------------------------------- 1 | # Palindrome Partitioning Memoization 2 | # https://www.geeksforgeeks.org/palindrome-partitioning-dp-17/ 3 | # https://leetcode.com/problems/palindrome-partitioning-ii/ 4 | 5 | import sys 6 | s = "nitik" 7 | 8 | dp = [[-1 for i in range(len(s))] for j in range(len(s))] 9 | 10 | def ispalindrome(s, i, j): 11 | if(i >= j): 12 | return True 13 | while i= j or ispalindrome(s, i, j)): 22 | return 0 23 | 24 | if(dp[i][j] != -1): 25 | return dp[i][j] 26 | 27 | mn = sys.maxsize 28 | 29 | for k in range(i, j): 30 | temp = solve(s, i, k) + solve(s, k+1, j) + 1 31 | mn = min(temp, mn) 32 | dp[i][j] = mn 33 | return mn 34 | 35 | print(solve(s, 0, len(s)-1)) -------------------------------------------------------------------------------- /DP/palpartmemopt.py: -------------------------------------------------------------------------------- 1 | # Palindrome Partitioning Memoization 2 | # https://www.geeksforgeeks.org/palindrome-partitioning-dp-17/ 3 | # https://leetcode.com/problems/palindrome-partitioning-ii/ 4 | 5 | import sys 6 | s = "nitik" 7 | 8 | dp = [[-1 for i in range(len(s))] for j in range(len(s))] 9 | 10 | def ispalindrome(s, i, j): 11 | if(i >= j): 12 | return True 13 | while i= j or ispalindrome(s, i, j)): 22 | return 0 23 | 24 | if(dp[i][j] != -1): 25 | return dp[i][j] 26 | 27 | mn = sys.maxsize 28 | 29 | for k in range(i, j): 30 | if(dp[i][k] != -1): 31 | left = dp[i][k] 32 | else: 33 | left = solve(s, i, k) 34 | dp[i][k] = left 35 | 36 | if(dp[k+1][j] != -1): 37 | right = dp[k+1][j] 38 | else: 39 | right = solve(s, k+1, j) 40 | dp[k+1][j] = right 41 | 42 | temp = left + right + 1 43 | mn = min(temp, mn) 44 | dp[i][j] = mn 45 | return mn 46 | 47 | print(solve(s, 0, len(s)-1)) -------------------------------------------------------------------------------- /DP/palpartrec.py: -------------------------------------------------------------------------------- 1 | # Palindrome Partitioning Recursive 2 | # https://www.geeksforgeeks.org/palindrome-partitioning-dp-17/ 3 | # https://leetcode.com/problems/palindrome-partitioning-ii/ 4 | 5 | import sys 6 | s = "nitik" 7 | 8 | def ispalindrome(s, i, j): 9 | if(i >= j): 10 | return True 11 | while i= j or ispalindrome(s, i, j)): 20 | return 0 21 | 22 | mn = sys.maxsize 23 | 24 | for k in range(i, j): 25 | temp = solve(s, i, k) + solve(s, k+1, j) + 1 26 | mn = min(temp, mn) 27 | 28 | return mn 29 | 30 | print(solve(s, 0, len(s)-1)) -------------------------------------------------------------------------------- /DP/plongestcomsubseq.py: -------------------------------------------------------------------------------- 1 | # Print Longest Common Subsequence 2 | # https://www.geeksforgeeks.org/printing-longest-common-subsequence/ 3 | 4 | x = "abcdaf" 5 | y = "acbcf" 6 | x = "AGGTAB" 7 | y = "GXTXAYB" 8 | x = "ABCDGH" 9 | y = "AEDFHR" 10 | n = len(x) 11 | m = len(y) 12 | 13 | dp = [] 14 | 15 | """ 16 | # More Time Consumed 17 | for i in range(n+1): 18 | a = [] 19 | for j in range(m+1): 20 | if(i==0 or j==0): 21 | a.append("") 22 | else: 23 | if(x[i-1] == y[j-1]): 24 | a.append(dp[i-1][j-1] + x[i-1]) 25 | else: 26 | if(len(dp[i-1][j])> len(a[j-1])): 27 | tmp_mx = dp[i-1][j] 28 | else: 29 | tmp_mx = a[j-1] 30 | a.append(tmp_mx) 31 | dp.append(a) 32 | 33 | #print(dp) 34 | print(dp[n][m]) 35 | 36 | # More Memory Consumed 37 | for i in range(n+1): 38 | a = [] 39 | for j in range(m+1): 40 | if(i==0 or j==0): 41 | a.append([0, ""]) 42 | else: 43 | if(x[i-1] == y[j-1]): 44 | a.append([1 + dp[i-1][j-1][0], dp[i-1][j-1][1] + x[i-1]]) 45 | else: 46 | if(dp[i-1][j][0]> a[j-1][0]): 47 | tmp_mx = [dp[i-1][j][0], dp[i-1][j][1]] 48 | else: 49 | tmp_mx = [a[j-1][0], a[j-1][1]] 50 | a.append(tmp_mx) 51 | dp.append(a) 52 | #print(dp) 53 | print(dp[n][m][1])""" 54 | -------------------------------------------------------------------------------- /DP/pshortestcomsupseq.py: -------------------------------------------------------------------------------- 1 | # Print shortest common Supersequence 2 | # 3 | 4 | x = "abcdaf" 5 | y = "acbcf" 6 | 7 | x = "abac" 8 | y = "cab" 9 | 10 | n = len(x) 11 | m = len(y) 12 | 13 | dp = [] 14 | 15 | for i in range(n + 1): 16 | a = [] 17 | for j in range(m + 1): 18 | if i == 0: 19 | a.append(j) 20 | elif j == 0: 21 | a.append(i) 22 | elif x[i - 1] == y[j - 1]: 23 | a.append(1 + dp[i - 1][j - 1]) 24 | else: 25 | a.append(1 + min(dp[i - 1][j], a[j - 1])) 26 | dp.append(a) 27 | 28 | st = "" 29 | 30 | while n > 0 and m > 0: 31 | if x[n - 1] == y[m - 1]: 32 | st = x[n - 1] + st 33 | n -= 1 34 | m -= 1 35 | elif dp[n - 1][m] > dp[n][m - 1]: 36 | st = y[m - 1] + st 37 | m -= 1 38 | else: 39 | st = x[n - 1] + st 40 | n -= 1 41 | 42 | while n > 0: 43 | st = x[n - 1] + st 44 | n -= 1 45 | 46 | while m > 0: 47 | st = y[m - 1] + st 48 | m -= 1 49 | 50 | print(st) -------------------------------------------------------------------------------- /DP/rodcut.py: -------------------------------------------------------------------------------- 1 | # Rod Cutting 2 | # https://www.geeksforgeeks.org/cutting-a-rod-dp-13/ 3 | 4 | length = [1,2,3,4,5,6,7,8] 5 | price = [1,5,8,9,10,17,17,20] 6 | n = 8 7 | sm = len(length) 8 | 9 | dp = [] 10 | 11 | for i in range(n+1): 12 | a = [] 13 | for j in range(sm+1): 14 | if(i==0 or j==0): 15 | a.append(0) 16 | else: 17 | if(length[i-1]<=j): 18 | a.append(max(price[i-1] + a[j-length[i-1]], dp[i-1][j])) 19 | else: 20 | a.append(dp[i-1][j]) 21 | dp.append(a) 22 | 23 | #print(dp) 24 | print(dp[n][sm]) -------------------------------------------------------------------------------- /DP/scrambledmem.py: -------------------------------------------------------------------------------- 1 | # Scrambled String Memoized 2 | # https://www.geeksforgeeks.org/check-if-a-string-is-a-scrambled-form-of-another-string/ 3 | # https://leetcode.com/problems/scramble-string/ 4 | 5 | s1 = "great" 6 | s2 = "eatgr" 7 | 8 | dp ={} 9 | 10 | def solve(a, b): 11 | if(a == b): 12 | return True 13 | 14 | if(len(a)<=1): 15 | return False 16 | 17 | st = a + " " + b 18 | 19 | if(st in dp): 20 | return dp[st] 21 | else: 22 | n = len(a) 23 | flag = False 24 | 25 | for i in range(1, n): 26 | # print(i) 27 | # print("a[:i]: " + a[:i] + " ,b[n-i:]: " + b[n-i:] + " ,a[i:]: " + a[i:] + " ,b[:n-i]: " + b[:n-i]) 28 | # print("a[:i]: " + a[:i] + " ,b[:i]: " + b[:i] + " ,a[i:]: " + a[i:] + " ,b[i:]: " + b[i:]) 29 | cond1 = solve(a[:i], b[n-i:]) and solve(a[i:], b[:n-i]) 30 | cond2 = solve(a[:i], b[:i]) and solve(a[i:], b[i:]) 31 | 32 | if(cond1 or cond2): 33 | flag = True 34 | break 35 | dp[st] = flag 36 | return flag 37 | 38 | print(solve(s1, s2)) -------------------------------------------------------------------------------- /DP/scrambledrec.py: -------------------------------------------------------------------------------- 1 | # Scrambled String Recursive 2 | # https://www.geeksforgeeks.org/check-if-a-string-is-a-scrambled-form-of-another-string/ 3 | # https://leetcode.com/problems/scramble-string/ 4 | 5 | s1 = "great" 6 | s2 = "eatgr" 7 | 8 | def solve(a, b): 9 | if(a == b): 10 | return True 11 | 12 | if(len(a)<=1): 13 | return False 14 | 15 | n = len(a) 16 | flag = False 17 | 18 | for i in range(1, n): 19 | print(i) 20 | print("a[:i]: " + a[:i] + " ,b[n-i:]: " + b[n-i:] + " ,a[i:]: " + a[i:] + " ,b[:n-i]: " + b[:n-i]) 21 | print("a[:i]: " + a[:i] + " ,b[:i]: " + b[:i] + " ,a[i:]: " + a[i:] + " ,b[i:]: " + b[i:]) 22 | cond1 = solve(a[:i], b[n-i:]) and solve(a[i:], b[:n-i]) 23 | cond2 = solve(a[:i], b[:i]) and solve(a[i:], b[i:]) 24 | 25 | if(cond1 or cond2): 26 | flag = True 27 | break 28 | 29 | return flag 30 | 31 | print(solve(s1, s2)) -------------------------------------------------------------------------------- /DP/seqpatternmat.py: -------------------------------------------------------------------------------- 1 | # Sequence Pattern Matching 2 | # 3 | 4 | x = "axy" 5 | y = "adxcpy" 6 | n = len(x) 7 | m = len(y) 8 | 9 | dp = [] 10 | 11 | for i in range(n+1): 12 | a = [] 13 | for j in range(m+1): 14 | if(i==0 or j==0): 15 | a.append(0) 16 | else: 17 | if(x[i-1] == y[j-1]): 18 | a.append(1 + dp[i-1][j-1]) 19 | else: 20 | a.append(max(dp[i-1][j], a[j-1])) 21 | dp.append(a) 22 | 23 | if(dp[n][m] == min(len(x), len(y))): 24 | print("True") 25 | else: 26 | print("False") -------------------------------------------------------------------------------- /DP/shortestcomsupseq.py: -------------------------------------------------------------------------------- 1 | # Shortest Common SuperSequence 2 | # https://practice.geeksforgeeks.org/problems/shortest-common-supersequence0322/1# 3 | 4 | x = "geek" 5 | y = "eke" 6 | n = len(x) 7 | m = len(y) 8 | 9 | dp = [] 10 | 11 | for i in range(n+1): 12 | a = [] 13 | for j in range(m+1): 14 | if(i==0 or j==0): 15 | a.append(0) 16 | else: 17 | if(x[i-1] == y[j-1]): 18 | a.append(1 + dp[i-1][j-1]) 19 | else: 20 | a.append(max(dp[i-1][j], a[j-1])) 21 | dp.append(a) 22 | 23 | print(n + m - dp[n][m]) -------------------------------------------------------------------------------- /DP/subsetsum.py: -------------------------------------------------------------------------------- 1 | # Subset Sum 2 | # https://practice.geeksforgeeks.org/problems/subset-sum-problem-1611555638/1/?category[]=Dynamic%20Programming&category[]=Dynamic%20Programming&page=4&query=category[]Dynamic%20Programmingpage4category[]Dynamic%20Programming 3 | arr = [2, 3, 7, 8, 10] 4 | sm = 11 5 | n = len(arr) 6 | 7 | dp = [] 8 | for i in range(n+1): 9 | a = [] 10 | for j in range(sm+1): 11 | if(i==0 and j==0): 12 | a.append(True) 13 | elif(i==0): 14 | a.append(False) 15 | elif(j==0): 16 | a.append(True) 17 | else: 18 | if(arr[i-1]<=j): 19 | a.append(dp[i-1][j-arr[i-1]] or dp[i-1][j]) 20 | else: 21 | a.append(dp[i-1][j]) 22 | dp.append(a) 23 | 24 | """for i in range(n+1): 25 | st = "" 26 | for j in range(sm+1): 27 | st += str(dp[i][j]) + " " 28 | print(st)""" 29 | 30 | print(dp[n][sm]) -------------------------------------------------------------------------------- /DP/targetsum.py: -------------------------------------------------------------------------------- 1 | # Target Sum 2 | # https://leetcode.com/problems/target-sum/ 3 | 4 | #arr = [1, 1, 2, 3] 5 | arr = [0, 0, 0, 0, 0, 1] 6 | df = 1 7 | n = len(arr) 8 | def targetsum(arr, n, df): 9 | sm = (df+sum(arr))/2 10 | if(sm == int(sm)): 11 | sm = int(sm) 12 | else: 13 | return 0 14 | 15 | dp = [] 16 | for i in range(n+1): 17 | a = [] 18 | for j in range(sm+1): 19 | if(i==0 and j==0): 20 | a.append(1) 21 | elif(i==0): 22 | a.append(0) 23 | elif(j==0): 24 | a.append(1) 25 | else: 26 | if(arr[i-1]<=j): 27 | a.append(dp[i-1][j-arr[i-1]] + dp[i-1][j]) 28 | else: 29 | a.append(dp[i-1][j]) 30 | dp.append(a) 31 | print(dp) 32 | return dp[n][sm] 33 | 34 | print(targetsum(arr, n, df)) -------------------------------------------------------------------------------- /DSA 450/Arrays/10minjumps.py: -------------------------------------------------------------------------------- 1 | # Minimum no. of Jumps to reach end of an array 2 | # https://practice.geeksforgeeks.org/problems/minimum-number-of-jumps-1587115620/1 3 | 4 | 5 | # Editorial Solution - Time Complexity: O(n) 6 | def minjump(arr, n): 7 | if(n<=1): 8 | return 0 9 | 10 | if(arr[0] == 0): 11 | return -1 12 | 13 | maxReach = arr[0] 14 | step = arr[0] 15 | jump = 1 16 | for i in range(1, n): 17 | if(i == n-1): 18 | return jump 19 | 20 | maxReach = max(maxReach, i+arr[i]) 21 | 22 | step -= 1 23 | 24 | if(step == 0): 25 | jump += 1 26 | 27 | if(i>=maxReach): 28 | return -1 29 | 30 | step = maxReach - i 31 | return -1 32 | 33 | ar = [1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9] 34 | 35 | #ar = [1, 4, 3, 2, 6, 7] 36 | 37 | #ar = [1, 3, 6, 3, 2, 3, 6, 8, 9, 5] 38 | 39 | #ar = [1, 3, 6, 1, 0, 9] 40 | 41 | #ar = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 42 | 43 | n = len(ar) 44 | 45 | print(minjump(ar, n)) 46 | -------------------------------------------------------------------------------- /DSA 450/Arrays/11dupar.py: -------------------------------------------------------------------------------- 1 | # find duplicate in an array of N+1 Integers 2 | # https://leetcode.com/problems/find-the-duplicate-number/ 3 | 4 | def findDuplicate(nums): 5 | nums.sort() 6 | for i in range(len(nums)-1): 7 | if(nums[i] == nums[i+1]): 8 | return(nums[i]) 9 | 10 | nums = [1,3,4,2,2] 11 | 12 | print(findDuplicate(nums)) 13 | 14 | # Other solution reference: https://www.youtube.com/watch?v=32Ll35mhWg0&t=383s -------------------------------------------------------------------------------- /DSA 450/Arrays/12merarr.py: -------------------------------------------------------------------------------- 1 | # Merge 2 sorted arrays without using Extra space. 2 | # https://practice.geeksforgeeks.org/problems/merge-two-sorted-arrays5135/1# 3 | 4 | # Own solution but not proper memory space 5 | def merge(arr1, arr2, n, m): 6 | arr1.extend(arr2) 7 | arr1.sort() 8 | for i in range(m): 9 | arr2[i] = arr1[n] 10 | arr1.pop(n) 11 | return 12 | 13 | n = 4 14 | m = 5 15 | arr1 = [1, 3, 5, 7] 16 | arr2 = [0, 2, 6, 8, 9] 17 | 18 | merge(arr1, arr2, n, m) 19 | 20 | for x in arr1: 21 | print(x, end = " ") 22 | 23 | for x in arr2: 24 | print(x, end = " ") -------------------------------------------------------------------------------- /DSA 450/Arrays/14merint.py: -------------------------------------------------------------------------------- 1 | # Merge Intervals 2 | # https://leetcode.com/problems/merge-intervals/ 3 | 4 | def merge(intervals): 5 | intervals.sort() 6 | a = [] 7 | a.append(intervals[0]) 8 | j = 0 9 | for i in range(1, len(intervals)): 10 | if(intervals[i][0]<=a[j][1]): 11 | a[j][0] = min([intervals[i][0], a[j][0]]) 12 | a[j][1] = max([intervals[i][1], a[j][1]]) 13 | else: 14 | a.append(intervals[i]) 15 | j += 1 16 | return a 17 | 18 | def merge2(intervals): 19 | intervals.sort() 20 | i = 0 21 | while(i=intervals[i+1][0]): 24 | intervals[i][0] = min([intervals[i][0], intervals[i+1][0]]) 25 | intervals[i][1] = max([intervals[i][1], intervals[i+1][1]]) 26 | intervals.pop(i+1) 27 | i -= 1 28 | i += 1 29 | return intervals 30 | 31 | ar = [[1,3],[2,6],[8,10],[15,18]] 32 | #ar = [[1,4],[4,5]] 33 | 34 | print(merge2(ar)) 35 | -------------------------------------------------------------------------------- /DSA 450/Arrays/15nextperm.py: -------------------------------------------------------------------------------- 1 | # Next Permutation 2 | # https://leetcode.com/problems/next-permutation/ 3 | 4 | # Leetcode solution - Time complexity: O(n) 5 | class Solution: 6 | def nextPermutation(self, nums: List[int]) -> None: 7 | i = len(nums) - 2 8 | while(i>=0 and nums[i+1]<=nums[i]): 9 | i-=1 10 | 11 | if(i>=0): 12 | j = len(nums) - 1 13 | while(j>=0 and nums[j]<=nums[i]): 14 | j-=1 15 | nums[i], nums[j] = nums[j], nums[i] 16 | def rev(nums1, start): 17 | i = start 18 | j = len(nums1)-1 19 | while(ia[j]): 10 | c+=1 11 | return c 12 | 13 | # GFG solution - Time Complexity: O(NlogN) 14 | def mergeSort(arr, n): 15 | # A temp_arr is created to store 16 | # sorted array in merge function 17 | temp_arr = [0]*n 18 | return _mergeSort(arr, temp_arr, 0, n-1) 19 | 20 | # This Function will use MergeSort to count inversions 21 | 22 | def _mergeSort(arr, temp_arr, left, right): 23 | 24 | # A variable inv_count is used to store 25 | # inversion counts in each recursive call 26 | 27 | inv_count = 0 28 | 29 | # We will make a recursive call if and only if 30 | # we have more than one elements 31 | 32 | if left < right: 33 | 34 | # mid is calculated to divide the array into two subarrays 35 | # Floor division is must in case of python 36 | 37 | mid = (left + right)//2 38 | 39 | # It will calculate inversion 40 | # counts in the left subarray 41 | 42 | inv_count += _mergeSort(arr, temp_arr, 43 | left, mid) 44 | 45 | # It will calculate inversion 46 | # counts in right subarray 47 | 48 | inv_count += _mergeSort(arr, temp_arr, 49 | mid + 1, right) 50 | 51 | # It will merge two subarrays in 52 | # a sorted subarray 53 | 54 | inv_count += merge(arr, temp_arr, left, mid, right) 55 | return inv_count 56 | 57 | # This function will merge two subarrays 58 | # in a single sorted subarray 59 | def merge(arr, temp_arr, left, mid, right): 60 | i = left # Starting index of left subarray 61 | j = mid + 1 # Starting index of right subarray 62 | k = left # Starting index of to be sorted subarray 63 | inv_count = 0 64 | 65 | # Conditions are checked to make sure that 66 | # i and j don't exceed their 67 | # subarray limits. 68 | 69 | while i <= mid and j <= right: 70 | 71 | # There will be no inversion if arr[i] <= arr[j] 72 | 73 | if arr[i] <= arr[j]: 74 | temp_arr[k] = arr[i] 75 | k += 1 76 | i += 1 77 | else: 78 | # Inversion will occur. 79 | temp_arr[k] = arr[j] 80 | inv_count += (mid-i + 1) 81 | k += 1 82 | j += 1 83 | 84 | # Copy the remaining elements of left 85 | # subarray into temporary array 86 | while i <= mid: 87 | temp_arr[k] = arr[i] 88 | k += 1 89 | i += 1 90 | 91 | # Copy the remaining elements of right 92 | # subarray into temporary array 93 | while j <= right: 94 | temp_arr[k] = arr[j] 95 | k += 1 96 | j += 1 97 | 98 | # Copy the sorted subarray into Original array 99 | for loop_var in range(left, right + 1): 100 | arr[loop_var] = temp_arr[loop_var] 101 | 102 | return inv_count 103 | 104 | # Other solution: https://www.geeksforgeeks.org/count-inversions-array-set-3-using-bit/ -------------------------------------------------------------------------------- /DSA 450/Arrays/18countpairs.py: -------------------------------------------------------------------------------- 1 | # find all pairs on integer array whose sum is equal to given number 2 | # https://practice.geeksforgeeks.org/problems/count-pairs-with-given-sum5022/1 3 | 4 | # GFG Solution - Time Complexity: O(n) 5 | def getPairsCount(self, arr, n, k): 6 | m = [0] * 10000000 7 | for i in arr: 8 | m[i] += 1 9 | c = 0 10 | for i in arr: 11 | c += m[k - i] 12 | 13 | if(k - i == i): 14 | c -= 1 15 | return int(c/2) 16 | 17 | # Own Solution - Time Complexity: O(n^2) 18 | def getPairsCount2(self, arr, n, k): 19 | c = 0 20 | for i in range(n): 21 | x = k - arr[i] 22 | c += arr[i+1:].count(x) 23 | return c -------------------------------------------------------------------------------- /DSA 450/Arrays/19commonnum.py: -------------------------------------------------------------------------------- 1 | # find common elements In 3 sorted arrays 2 | # https://practice.geeksforgeeks.org/problems/common-elements1132/1 3 | 4 | # Own solution 5 | def commonElements(A, B, C, n1, n2, n3): 6 | cm = list(set(A).intersection(set(B), set(C))) 7 | cm.sort() 8 | return cm 9 | 10 | # GFG Solution - Time Complexit: O(n1 + n2 + n3) 11 | def commonElements2(A, B, C, n1, n2, n3): 12 | cm = [] 13 | i, j, k = 0, 0, 0 14 | while (i < n1 and j < n2 and k< n3): 15 | if (A[i] == B[j] and B[j] == C[k]): 16 | if(A[i] not in cm): 17 | cm.append(A[i]) 18 | i += 1 19 | j += 1 20 | k += 1 21 | 22 | elif A[i] < B[j]: 23 | i += 1 24 | 25 | elif B[j] < C[k]: 26 | j += 1 27 | 28 | else: 29 | k += 1 30 | return cm 31 | 32 | n1 = 6 33 | A = [1, 5, 10, 20, 40, 80] 34 | n2 = 5 35 | B = [6, 7, 20, 80, 100] 36 | n3 = 8 37 | C = [3, 4, 15, 20, 30, 70, 80, 120] 38 | 39 | print(commonElements(A, B, C, n1, n2, n3)) 40 | print(commonElements2(A, B, C, n1, n2, n3)) -------------------------------------------------------------------------------- /DSA 450/Arrays/1revarray.py: -------------------------------------------------------------------------------- 1 | # Reverse the array 2 | # https://www.geeksforgeeks.org/write-a-program-to-reverse-an-array-or-string/ 3 | 4 | a = [4, 7, 2, 8, 5, 1] 5 | b = [7, 2, 4, 0, 1, 5, 7] 6 | 7 | # Using Python list slicing 8 | print(b[::-1]) 9 | 10 | # GFG Iterative solution 11 | # Time Complexity : O(n) 12 | def revar(arr): 13 | start = 0 14 | end = len(arr) - 1 15 | while(start < end): 16 | temp = arr[start] 17 | arr[start] = arr[end] 18 | arr[end] = temp 19 | start += 1 20 | end -= 1 21 | return arr 22 | 23 | # Here the list/array is passed itself so it changes after executing this 24 | print(revar(b)) 25 | 26 | # There is another solution using Recursive approach which has same Time Complexity : O(n) -------------------------------------------------------------------------------- /DSA 450/Arrays/20altnegpos.py: -------------------------------------------------------------------------------- 1 | # Rearrange the array in alternating positive and negative items with O(1) extra space 2 | # https://www.geeksforgeeks.org/rearrange-array-alternating-positive-negative-items-o1-extra-space/ 3 | 4 | # Own solution - Time Complexity: O(n) 5 | def altnegpos(arr): 6 | arr.sort() 7 | n = 0 8 | for i in range(len(arr)): 9 | if(arr[i]>=0): 10 | n = i 11 | break 12 | 13 | for i in range(len(arr)): 14 | if((i+1)%2 == 0 and arr[i]<0): 15 | arr[i], arr[n] = arr[n], arr[i] 16 | n += 1 17 | 18 | #GFG Solution - Time Complexit: O(n) 19 | def rightRotate(arr, n, outOfPlace, cur): 20 | temp = arr[cur] 21 | for i in range(cur, outOfPlace, -1): 22 | arr[i] = arr[i - 1] 23 | arr[outOfPlace] = temp 24 | return arr 25 | 26 | 27 | def rearrange(arr, n): 28 | outOfPlace = -1 29 | for index in range(n): 30 | if(outOfPlace >= 0): 31 | if((arr[index] >= 0 and arr[outOfPlace] < 0) or 32 | (arr[index] < 0 and arr[outOfPlace] >= 0)): 33 | arr = rightRotate(arr, n, outOfPlace, index) 34 | if(index-outOfPlace > 2): 35 | outOfPlace += 2 36 | else: 37 | outOfPlace = - 1 38 | 39 | if(outOfPlace == -1): 40 | if((arr[index] >= 0 and index % 2 == 0) or 41 | (arr[index] < 0 and index % 2 == 1)): 42 | outOfPlace = index 43 | return arr 44 | 45 | #ar = [1, 2, 3, -4, -1, 4] 46 | 47 | ar = [-5, -2, 5, 2, 4, 7, 1, 8, 0, -8] 48 | 49 | altnegpos(ar) 50 | 51 | print(ar) -------------------------------------------------------------------------------- /DSA 450/Arrays/21sub0.py: -------------------------------------------------------------------------------- 1 | # Find if there is any subarray with sum equal to 0 2 | # https://practice.geeksforgeeks.org/problems/subarray-with-0-sum-1587115621/1 3 | 4 | # GFG solution - Time Complexity: O(n) 5 | def subArrayExists(arr,n): 6 | n_sum = 0 7 | s = set() 8 | 9 | for i in range(n): 10 | n_sum += arr[i] 11 | 12 | if n_sum == 0 or n_sum in s: 13 | return True 14 | s.add(n_sum) 15 | 16 | return False -------------------------------------------------------------------------------- /DSA 450/Arrays/22factorial.py: -------------------------------------------------------------------------------- 1 | # Find factorial of a large number 2 | # https://practice.geeksforgeeks.org/problems/factorials-of-large-numbers/0 3 | 4 | # Own solution using recursion 5 | def fact(n): 6 | if(n == 0 or n ==1): 7 | return 1 8 | else: 9 | return fact(n-1)*n 10 | 11 | # Own solution using while loop 12 | def fact2(n): 13 | f = 1 14 | if(n == 0): 15 | return f 16 | while(n != 1): 17 | f = f*(n) 18 | n = n-1 19 | return f 20 | 21 | """n = int(input()) 22 | 23 | for i in range(n): 24 | print(fact(int(input())))""" -------------------------------------------------------------------------------- /DSA 450/Arrays/23maxprod.py: -------------------------------------------------------------------------------- 1 | # find maximum product subarray 2 | # https://practice.geeksforgeeks.org/problems/maximum-product-subarray3604/1 3 | 4 | # Own solution - Time Complexity: O(N^2) 5 | def maxProduct(arr, n): 6 | res = 1 7 | 8 | for i in range(n): 9 | prod = 1 10 | prod *= arr[i] 11 | if(prod==0): 12 | prod = 1 13 | if(prod > res): 14 | res = prod 15 | for j in range(i+1, n): 16 | prod *= arr[j] 17 | if(prod==0): 18 | prod = 1 19 | if(prod > res): 20 | res = prod 21 | return res 22 | 23 | # GFG Solution - Time Complexity: O(N) 24 | def maxsubarrayproduct(arr, n): 25 | max_ending_here = 1 26 | min_ending_here = 1 27 | max_so_far = 0 28 | flag = 0 29 | 30 | for i in range(0, n): 31 | if arr[i] > 0: 32 | max_ending_here = max_ending_here * arr[i] 33 | min_ending_here = min (min_ending_here * arr[i], 1) 34 | flag = 1 35 | 36 | elif arr[i] == 0: 37 | max_ending_here = 1 38 | min_ending_here = 1 39 | 40 | else: 41 | temp = max_ending_here 42 | max_ending_here = max (min_ending_here * arr[i], 1) 43 | min_ending_here = temp * arr[i] 44 | if (max_so_far < max_ending_here): 45 | max_so_far = max_ending_here 46 | 47 | if flag == 0 and max_so_far == 0: 48 | return 0 49 | return max_so_far 50 | 51 | #Leetcode discussion solution - Time Complexity: O(N) 52 | def maxProduct2(nums, n): 53 | curr_max = global_max = curr_min = nums[0] 54 | 55 | for i in range(1,n): 56 | #print("First", global_max, curr_max, curr_min) 57 | #print("Second", nums[i], nums[i] * curr_max, nums[i] * curr_min) 58 | curr_max, curr_min = max(nums[i], nums[i] * curr_max, nums[i] * curr_min), min(nums[i], nums[i] * curr_max, nums[i] * curr_min) 59 | #print("Third", global_max, curr_max, curr_min) 60 | global_max = max(global_max, curr_max) 61 | 62 | 63 | return global_max 64 | 65 | arr = [6, -3, -10, 0, 2] 66 | n = 5 67 | 68 | print(maxProduct(arr, n)) 69 | print(maxsubarrayproduct(arr, n)) 70 | print(maxProduct2(arr, n)) -------------------------------------------------------------------------------- /DSA 450/Arrays/24consub.py: -------------------------------------------------------------------------------- 1 | # Find longest coinsecutive subsequence 2 | # https://practice.geeksforgeeks.org/problems/longest-consecutive-subsequence2449/1 3 | 4 | # Own Solution - Time Complexit: O(NlogN) 5 | def findLongestConseqSubseq(arr, N): 6 | arr.sort() 7 | arr1 = list(set(arr)) 8 | mx = 1 9 | temp = 1 10 | for i in range(len(arr1)-1): 11 | if(arr1[i+1]-arr1[i]==1): 12 | temp += 1 13 | else: 14 | temp = 1 15 | if(temp>mx): 16 | mx = temp 17 | return mx 18 | 19 | arr = [1,9,3,10,4,20,2] 20 | n = len(arr) 21 | 22 | # Own Solution based on GFG - Time Complexity: O(N) 23 | def findLongestConseqSubseq2(arr, N): 24 | arr1 = set(arr) 25 | mx = 1 26 | for i in arr1: 27 | temp = 1 28 | while i+1 in arr1: 29 | temp += 1 30 | i += 1 31 | if(temp>mx): 32 | mx = temp 33 | return mx 34 | 35 | # Other GFG solutions: https://www.geeksforgeeks.org/longest-consecutive-subsequence/ 36 | 37 | arr = [1,9,3,10,4,20,2] 38 | arr = [3, 7, 10, 12, 4, 39, 80, 5, 12, 10, 8, 3, 6, 7, 9, 11] 39 | n = len(arr) 40 | 41 | print(findLongestConseqSubseq(arr, n)) 42 | print(findLongestConseqSubseq2(arr, n)) -------------------------------------------------------------------------------- /DSA 450/Arrays/25nbykocc.py: -------------------------------------------------------------------------------- 1 | # Given an array of size n and a number k, fin all elements that appear more than " n/k " times. 2 | # https://www.geeksforgeeks.org/given-an-array-of-of-size-n-finds-all-the-elements-that-appear-more-than-nk-times/ 3 | 4 | # Hashing solution - Time Complexity: O(N) 5 | def nbykocc(arr, n, k): 6 | occ = {} 7 | 8 | for i in arr: 9 | if(i in occ): 10 | occ[i] += 1 11 | else: 12 | occ[i] = 1 13 | 14 | nk = [] 15 | 16 | for i in occ: 17 | if(occ[i]>n//k): 18 | nk.append(i) 19 | 20 | return nk 21 | 22 | 23 | # Other solutions on GFG 24 | 25 | arr = [ 1, 1, 2, 2, 3, 5, 4, 2, 2, 3, 1, 3, 1, 3] 26 | n = len(arr) 27 | k = 4 28 | 29 | print(n//k) 30 | 31 | print(nbykocc(arr, n, k)) -------------------------------------------------------------------------------- /DSA 450/Arrays/26maxprofit.py: -------------------------------------------------------------------------------- 1 | # Maximum profit by buying and selling a share atmost twice 2 | # https://www.geeksforgeeks.org/maximum-profit-by-buying-and-selling-a-share-at-most-twice/ 3 | 4 | # GFG using DP - Time Complexit: O(N) 5 | def maxProfit(price, n): 6 | profit = [0]*n 7 | 8 | max_price = price[n-1] 9 | 10 | for i in range(n-2, 0, -1): 11 | if price[i] > max_price: 12 | max_price = price[i] 13 | 14 | profit[i] = max(profit[i+1], max_price - price[i]) 15 | #print(profit, max_price, price[i]) 16 | 17 | min_price = price[0] 18 | #print("Min") 19 | for i in range(1, n): 20 | if price[i] < min_price: 21 | min_price = price[i] 22 | 23 | profit[i] = max(profit[i-1], profit[i]+(price[i]-min_price)) 24 | #print(profit, min_price, price[i]) 25 | 26 | result = profit[n-1] 27 | 28 | return result 29 | 30 | arr = [2, 30, 15, 10, 8, 25, 80] 31 | n = 7 32 | 33 | arr = [10, 22, 5, 75, 65, 80] 34 | n = 6 35 | 36 | arr = [100, 30, 15, 10, 8, 25, 80] 37 | n = 7 38 | 39 | print(maxProfit(arr, n)) -------------------------------------------------------------------------------- /DSA 450/Arrays/27subarr.py: -------------------------------------------------------------------------------- 1 | # Find whether an array is a subset of another arra 2 | # https://practice.geeksforgeeks.org/problems/array-subset-of-another-array/0# 3 | 4 | # Own solution - Time Complexity: O(MN) 5 | def sub(arr1, arr2, l2): 6 | count = 0 7 | for k in range(l2): 8 | if(arr2[k] in arr1): 9 | count += 1 10 | if(l2 == count): 11 | return "Yes" 12 | else: 13 | return "No" 14 | 15 | # Own Solution 2 using Hashing - Time complexit: O(M+N) 16 | def sub2(arr1, arr2, l1, l2): 17 | ar1 = {} 18 | ar2 = {} 19 | for j in range(l1): 20 | if(arr1[j] in ar1): 21 | ar1[arr1[j]] += 1 22 | else: 23 | ar1[arr1[j]] = 1 24 | 25 | for k in range(l2): 26 | if(arr2[k] in ar2): 27 | ar2[arr2[k]] += 1 28 | else: 29 | ar2[arr2[k]] = 1 30 | 31 | count = 0 32 | 33 | for l in ar2: 34 | if(l in ar1 and ar1[l]>=ar2[l]): 35 | count += 1 36 | 37 | if(l2 == count): 38 | return "Yes" 39 | else: 40 | return "No" -------------------------------------------------------------------------------- /DSA 450/Arrays/28tripletsum.py: -------------------------------------------------------------------------------- 1 | # Find the triplet that sum to a given value 2 | # https://practice.geeksforgeeks.org/problems/triplet-sum-in-array-1587115621/1 3 | 4 | # GFG Sollution using Hashing - Time Complexity: O(N^2) 5 | def find3Numbers(arr, N, X): 6 | for i in range(N): 7 | s = set() 8 | curr_sum = X - arr[i] 9 | for j in range(i + 1, N): 10 | if (curr_sum - arr[j]) in s: 11 | return True 12 | s.add(arr[j]) -------------------------------------------------------------------------------- /DSA 450/Arrays/29rainwater.py: -------------------------------------------------------------------------------- 1 | # Trapping Rain water problem 2 | # https://practice.geeksforgeeks.org/problems/trapping-rain-water-1587115621/1 3 | 4 | # Left and right max - Time Complexity: O(N^2) 5 | def trappingWater(arr): 6 | n = len(arr) 7 | res = 0 8 | for i in range(n): 9 | left = arr[i] 10 | right = arr[i] 11 | l = i-1 12 | r = i+1 13 | while(l>=0): 14 | if(arr[l]>left): 15 | left = arr[l] 16 | l -= 1 17 | 18 | while(rright): 20 | right = arr[r] 21 | r += 1 22 | res += min(left, right) - arr[i] 23 | return res 24 | 25 | # Using 2 pointers - Time Complexity: O(N) 26 | def trap(height): 27 | i = 0 28 | j = len(height)-1 29 | left_max = 0 30 | right_max = 0 31 | res = 0 32 | while(i=left_max): 35 | left_max = height[i] 36 | else: 37 | res += left_max - height[i] 38 | i+=1 39 | else: 40 | if(height[j]>=right_max): 41 | right_max = height[j] 42 | else: 43 | res += right_max - height[j] 44 | j-=1 45 | return res 46 | 47 | arr = [0,1,0,2,1,0,1,3,2,1,2,1] 48 | 49 | print(trappingWater(arr)) 50 | print(trap(arr)) -------------------------------------------------------------------------------- /DSA 450/Arrays/2maxmin.py: -------------------------------------------------------------------------------- 1 | # Find the maximum and minimum element in an array 2 | # https://www.geeksforgeeks.org/maximum-and-minimum-in-an-array/ 3 | 4 | # Simple Linear Search 5 | # Time Complexity: O(n) 6 | 7 | def minmax(arr): 8 | l = len(arr) 9 | 10 | if(l == 1): 11 | return("Minimum: " + str(arr[0]) + ", Maximum: " + str(arr[0])) 12 | else: 13 | if(arr[0]>arr[1]): 14 | mini = arr[1] 15 | maxi = arr[0] 16 | else: 17 | mini = arr[0] 18 | maxi = arr[1] 19 | for i in range(2, l): 20 | if(arr[i] > maxi): 21 | maxi = arr[i] 22 | if(arr[i] < mini): 23 | mini = arr[i] 24 | return("Minimum: " + str(mini) + ", Maximum: " + str(maxi)) 25 | 26 | a = [1000, 11, 445, 7, 330, 3000] 27 | 28 | print(minmax(a)) 29 | 30 | ''' There are other solutions using Tournament Method in which the array is split into 2 parts and the minimum and maximum is 31 | found for each part. Apart from that, there is another solution in which the minimum and maximum is checked in pairs by first 32 | initializing min and max with starting 2 elements if there are even number of elements and then compared in pairs or intialise 33 | min and max with first element if there are odd number of elements and then compared in pairs. All these methos have same 34 | time complexity of O(n). ''' 35 | 36 | # Own solution 37 | def minmax2(arr): 38 | arr.sort() 39 | return("Minimum: " + str(arr[0]) + ", Maximum: " + str(arr[-1])) 40 | 41 | print(minmax2(a)) -------------------------------------------------------------------------------- /DSA 450/Arrays/30chocdis.py: -------------------------------------------------------------------------------- 1 | # Chocolate Distribution Problem 2 | # https://practice.geeksforgeeks.org/problems/chocolate-distribution-problem3825/1# 3 | 4 | # Own Solution - Time Complexity: O(NLogN) 5 | # Similar/same solution on GFG 6 | def findMinDiff(A,N,M): 7 | A.sort() 8 | res = 99999999999 9 | for i in range(N-M+1): 10 | tmp = A[i+M-1] - A[i] 11 | if(tmp0 and arr[r]>0): 25 | r -= 1 26 | elif(arr[l]>0 and arr[r]<0): 27 | temp = arr[l] 28 | arr[l] = arr[r] 29 | arr[r] = temp 30 | l += 1 31 | r -= 1 32 | else: 33 | l += 1 34 | r -= 1 35 | return arr 36 | 37 | # Own Approach 1 - More memory consumption 38 | 39 | def negmov3(arr): 40 | a = [] 41 | b = [] 42 | for i in range(len(arr)): 43 | if(arr[i]<0): 44 | a.append(arr[i]) 45 | else: 46 | b.append(arr[i]) 47 | return(a+b) 48 | 49 | 50 | # Own Approach 2 - Using inbuilt sort function 51 | def negmov4(arr): 52 | arr.sort() 53 | return arr 54 | 55 | ar = [-12, 11, -13, -5, 6, -7, 5, -3, -6] 56 | 57 | print(negmov4(ar)) -------------------------------------------------------------------------------- /DSA 450/Arrays/6arruni.py: -------------------------------------------------------------------------------- 1 | # Find the Union and Intersection of the two sorted arrays. 2 | # https://practice.geeksforgeeks.org/problems/union-of-two-arrays3538/1 3 | 4 | # Own Solution 5 | 6 | def doUnion(a,n,b,m): 7 | c = [] 8 | for i in range(n): 9 | if(a[i] not in c): 10 | c.append(a[i]) 11 | for j in range(m): 12 | if(b[j] not in c): 13 | c.append(b[j]) 14 | return len(c) 15 | 16 | a = [85, 25, 1, 32, 54, 6] 17 | b = [85, 2] 18 | n = 6 19 | m = 2 20 | 21 | print(doUnion(a,n,b,m)) 22 | -------------------------------------------------------------------------------- /DSA 450/Arrays/7clockrev.py: -------------------------------------------------------------------------------- 1 | # Write a program to cyclically rotate an array by one. 2 | # https://practice.geeksforgeeks.org/problems/cyclically-rotate-an-array-by-one2614/1# 3 | 4 | # GFG Approach Time Complexity: O(n) 5 | def rotate( arr, n): 6 | a = arr[-1] 7 | for i in range(n-1, 0, -1): 8 | arr[i] = arr[i-1] 9 | arr[0] = a 10 | return arr 11 | 12 | # Own approach if given array need not be changed by itself more space 13 | def rotate2(arr): 14 | a = [arr[-1]] + arr[:-1] 15 | return a 16 | 17 | ar = [1, 2, 3, 4, 5] 18 | 19 | print(rotate2(ar)) 20 | 21 | print(rotate(ar, len(ar))) -------------------------------------------------------------------------------- /DSA 450/Arrays/8maxsubsum.py: -------------------------------------------------------------------------------- 1 | # find Largest sum contiguous Subarray [V. IMP] 2 | # https://practice.geeksforgeeks.org/problems/kadanes-algorithm-1587115620/1 3 | 4 | # Kadane's Algorithm Time Complexity: O(n) 5 | # Algorithmic Paradigm: Dynamic Programming 6 | 7 | def maxSubArraySum(a,size): 8 | msf = 0 9 | mtn = 0 10 | for i in range(size): 11 | mtn += a[i] 12 | if(msf=len(numbers_list) or mid_index<0): 39 | return -1 40 | 41 | mid_number = numbers_list[mid_index] 42 | 43 | if(mid_number == number_to_find): 44 | return mid_index 45 | 46 | if(mid_numberself.data): 79 | if(self.right): 80 | self.right = self.right.delete(val) 81 | else: 82 | if(self.left is None and self.right is None): 83 | return None 84 | if(self.left is None): 85 | return self.right 86 | if(self.right is None): 87 | return self.left 88 | 89 | min_val = self.right.find_min() 90 | self.data = min_val 91 | self.right = self.right.delete(min_val) 92 | 93 | return self 94 | 95 | def search(self, val): 96 | if(self.data == val): 97 | return True 98 | 99 | if(valself.data): 106 | if self.right: 107 | return self.right.search(val) 108 | else: 109 | return False 110 | 111 | def build_tree(elements): 112 | root = BinarySearchTreeNode(elements[0]) 113 | 114 | for i in range(1, len(elements)): 115 | root.add_child(elements[i]) 116 | 117 | return root 118 | 119 | if __name__ == '__main__': 120 | numbers = [17, 4, 1, 20, 9, 23, 18, 34] 121 | numbers_tree = build_tree(numbers) 122 | print(numbers_tree.in_order_traversal()) 123 | print(numbers_tree.search(20)) 124 | print(numbers_tree.search(21)) 125 | print(numbers_tree.search(200)) 126 | numbers_tree.delete(20) 127 | print(numbers_tree.in_order_traversal()) 128 | 129 | countires = ["India", "Pakistan", "Germany", "USA", "China", "India", "UK", "USA"] 130 | country_tree = build_tree(countires) 131 | print(country_tree.in_order_traversal()) 132 | print("UK is in the tree?", country_tree.search("UK")) 133 | print("Sweden is in the tree?", country_tree.search("Sweden")) 134 | 135 | numbers = [17, 4, 1, 20, 9, 23, 18, 34] 136 | 137 | numbers = [15,12,7,14,27,20,23,88 ] 138 | 139 | numbers_tree = build_tree(numbers) 140 | print("Input numbers:",numbers) 141 | print("Min:",numbers_tree.find_min()) 142 | print("Max:",numbers_tree.find_max()) 143 | print("Sum:", numbers_tree.calculate_sum()) 144 | print("In order traversal:", numbers_tree.in_order_traversal()) 145 | print("Pre order traversal:", numbers_tree.pre_order_traversal()) 146 | print("Post order traversal:", numbers_tree.post_order_traversal()) -------------------------------------------------------------------------------- /DSA-Python/bubble_sort.py: -------------------------------------------------------------------------------- 1 | def bubble_sort(elements): 2 | size = len(elements) 3 | 4 | for i in range(size-1): 5 | swapped = False 6 | for j in range(size-1-i): 7 | if(elements[j]>elements[j+1]): 8 | elements[j], elements[j+1] = elements[j+1], elements[j] 9 | swapped = True 10 | 11 | if not swapped: 12 | break 13 | 14 | if __name__ == "__main__": 15 | elements = [5, 9, 2, 1, 67, 34, 88, 34] 16 | #elements = [1, 2, 3, 4, 2] 17 | #elements = [1, 2, 3, 4] 18 | #elements = ["mona", "dhaval", "aamir", "tina", "chang"] 19 | 20 | bubble_sort(elements) 21 | print(elements) -------------------------------------------------------------------------------- /DSA-Python/doubly_linked_list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, data=None, next=None, prev=None): 3 | self.data = data 4 | self.next = next 5 | self.prev = prev 6 | 7 | class DoublyLinkedList: 8 | def __init__(self): 9 | self.head = None 10 | 11 | def print_forward(self): 12 | if self.head is None: 13 | print("Linked list is empty") 14 | return 15 | 16 | itr = self.head 17 | llstr = '' 18 | while itr: 19 | llstr += str(itr.data) + ' --> ' 20 | itr = itr.next 21 | print(llstr) 22 | 23 | def print_backward(self): 24 | if self.head is None: 25 | print("Linked list is empty") 26 | return 27 | 28 | last_node = self.get_last_node() 29 | itr = last_node 30 | llstr = '' 31 | while itr: 32 | llstr += itr.data + '-->' 33 | itr = itr.prev 34 | print("Link list in reverse: ", llstr) 35 | 36 | def get_last_node(self): 37 | itr = self.head 38 | while itr.next: 39 | itr = itr.next 40 | 41 | return itr 42 | 43 | def get_length(self): 44 | count = 0 45 | itr = self.head 46 | while itr: 47 | count+=1 48 | itr = itr.next 49 | 50 | return count 51 | 52 | def insert_at_begining(self, data): 53 | if self.head == None: 54 | node = Node(data, self.head, None) 55 | self.head = node 56 | else: 57 | node = Node(data, self.head, None) 58 | self.head.prev = node 59 | self.head = node 60 | 61 | def insert_at_end(self, data): 62 | if self.head is None: 63 | self.head = Node(data, None, None) 64 | return 65 | 66 | itr = self.head 67 | 68 | while itr.next: 69 | itr = itr.next 70 | 71 | itr.next = Node(data, None, itr) 72 | 73 | def insert_at(self, index, data): 74 | if index<0 or index>self.get_length(): 75 | raise Exception("Invalid Index") 76 | 77 | if index==0: 78 | self.insert_at_begining(data) 79 | return 80 | 81 | count = 0 82 | itr = self.head 83 | while itr: 84 | if count == index - 1: 85 | node = Node(data, itr.next, itr) 86 | if node.next: 87 | node.next.prev = node 88 | itr.next = node 89 | break 90 | 91 | itr = itr.next 92 | count += 1 93 | 94 | def remove_at(self, index): 95 | if index<0 or index>=self.get_length(): 96 | raise Exception("Invalid Index") 97 | 98 | if index==0: 99 | self.head = self.head.next 100 | self.head.prev = None 101 | return 102 | 103 | count = 0 104 | itr = self.head 105 | while itr: 106 | if count == index: 107 | itr.prev.next = itr.next 108 | if itr.next: 109 | itr.next.prev = itr.prev 110 | break 111 | 112 | itr = itr.next 113 | count+=1 114 | 115 | def insert_values(self, data_list): 116 | self.head = None 117 | for data in data_list: 118 | self.insert_at_end(data) 119 | 120 | 121 | if __name__ == '__main__': 122 | ll = DoublyLinkedList() 123 | ll.insert_values(["banana","mango","grapes","orange"]) 124 | ll.print_forward() 125 | ll.print_backward() 126 | ll.insert_at_end("figs") 127 | ll.print_forward() 128 | ll.insert_at(0,"jackfruit") 129 | ll.print_forward() 130 | ll.insert_at(6,"dates") 131 | ll.print_forward() 132 | ll.insert_at(2,"kiwi") 133 | ll.print_forward() -------------------------------------------------------------------------------- /DSA-Python/graph.py: -------------------------------------------------------------------------------- 1 | class Graph: 2 | def __init__(self, edges): 3 | self.edges = edges 4 | self.graph_dict = {} 5 | for start, end in self.edges: 6 | if(start in self.graph_dict): 7 | self.graph_dict[start].append(end) 8 | else: 9 | self.graph_dict[start] = [end] 10 | print("Graph dict:", self.graph_dict) 11 | 12 | def get_paths(self, start, end, path=[]): 13 | path = path + [start] 14 | 15 | if(start == end): 16 | return [path] 17 | 18 | if(start not in self.graph_dict): 19 | return [] 20 | 21 | paths = [] 22 | 23 | for node in self.graph_dict[start]: 24 | if node not in path: 25 | new_paths = self.get_paths(node, end, path) 26 | for p in new_paths: 27 | paths.append(p) 28 | 29 | return paths 30 | 31 | def get_shortest_path(self, start, end, path=[]): 32 | path = path + [start] 33 | 34 | if(start == end): 35 | return path 36 | 37 | if(start not in self.graph_dict): 38 | return None 39 | 40 | shortest_path = None 41 | 42 | for node in self.graph_dict[start]: 43 | if(node not in path): 44 | sp = self.get_shortest_path(node, end, path) 45 | if sp: 46 | if(shortest_path is None or len(sp) < len(shortest_path)): 47 | shortest_path = sp 48 | 49 | return shortest_path 50 | 51 | if __name__ == '__main__': 52 | routes = { 53 | ("Mumbai","Paris"), 54 | ("Mumbai","Dubai"), 55 | ("Paris","Dubai"), 56 | ("Paris", "New York"), 57 | ("Dubai", "New York"), 58 | ("New York", "Toronto") 59 | } 60 | 61 | route_graph = Graph(routes) 62 | 63 | start = "Mumbai" 64 | end = "New York" 65 | print(f"Paths between {start} and {end}: ", route_graph.get_paths(start, end)) 66 | print(f"Shortest path between {start} and {end}: ", route_graph.get_shortest_path(start, end)) -------------------------------------------------------------------------------- /DSA-Python/hash_maps.py: -------------------------------------------------------------------------------- 1 | class HashTable: 2 | def __init__(self): 3 | self.MAX = 100 4 | self.arr = [[] for i in range(self.MAX)] 5 | 6 | def get_hash(self, key): 7 | h = 0 8 | for char in key: 9 | h += ord(char) 10 | return h%self.MAX 11 | 12 | def __setitem__(self, key, val): 13 | h = self.get_hash(key) 14 | found = False 15 | for idx, element in enumerate(self.arr[h]): 16 | if(len(element)==2 and element[0]==key): 17 | self.arr[h][idx] = (key, val) 18 | found = True 19 | break 20 | if not found: 21 | self.arr[h].append((key, val)) 22 | 23 | def __getitem__(self, key): 24 | h = self.get_hash(key) 25 | for element in self.arr[h]: 26 | if element[0] == key: 27 | return element[1] 28 | 29 | def __delitem__(self, key): 30 | h = self.get_hash(key) 31 | for idx, element in enumerate(self.arr[h]): 32 | if element[0] == key: 33 | del self.arr[h][idx] 34 | 35 | t = HashTable() 36 | t['march 6'] = 120 37 | t['march 6'] = 78 38 | t['march 8'] = 67 39 | t['march 9'] = 4 40 | t['march 17'] = 459 41 | #del t['march 6'] 42 | print(t['march 17']) 43 | del t['march 17'] 44 | print(t.arr) 45 | 46 | # Hash table with linear probing collision handling 47 | 48 | """class HashTable: 49 | def __init__(self): 50 | self.MAX = 10 # I am keeping size very low to demonstrate linear probing easily but usually the size should be high 51 | self.arr = [None for i in range(self.MAX)] 52 | 53 | def get_hash(self, key): 54 | hash = 0 55 | for char in key: 56 | hash += ord(char) 57 | return hash % self.MAX 58 | 59 | def __getitem__(self, key): 60 | h = self.get_hash(key) 61 | if self.arr[h] is None: 62 | return 63 | prob_range = self.get_prob_range(h) 64 | for prob_index in prob_range: 65 | element = self.arr[prob_index] 66 | if element is None: 67 | return 68 | if element[0] == key: 69 | return element[1] 70 | 71 | def __setitem__(self, key, val): 72 | h = self.get_hash(key) 73 | if self.arr[h] is None: 74 | self.arr[h] = (key,val) 75 | else: 76 | new_h = self.find_slot(key, h) 77 | self.arr[new_h] = (key,val) 78 | print(self.arr) 79 | 80 | def get_prob_range(self, index): 81 | return [*range(index, len(self.arr))] + [*range(0,index)] 82 | 83 | def find_slot(self, key, index): 84 | prob_range = self.get_prob_range(index) 85 | for prob_index in prob_range: 86 | if self.arr[prob_index] is None: 87 | return prob_index 88 | if self.arr[prob_index][0] == key: 89 | return prob_index 90 | raise Exception("Hashmap full") 91 | 92 | def __delitem__(self, key): 93 | h = self.get_hash(key) 94 | prob_range = self.get_prob_range(h) 95 | for prob_index in prob_range: 96 | if self.arr[prob_index] is None: 97 | return # item not found so return. You can also throw exception 98 | if self.arr[prob_index][0] == key: 99 | self.arr[prob_index]=None 100 | print(self.arr)""" -------------------------------------------------------------------------------- /DSA-Python/insertion_sort.py: -------------------------------------------------------------------------------- 1 | def insertion_sort(elements): 2 | for i in range(1, len(elements)): 3 | anchor = elements[i] 4 | j = i - 1 5 | while j>=0 and anchor < elements[j]: 6 | elements[j+1] = elements[j] 7 | j = j - 1 8 | elements[j+1] = anchor 9 | 10 | if __name__ == "__main__": 11 | tests = [ 12 | [10, 3, 15, 7, 8, 23, 98, 29], 13 | [25, 22, -1, 21, 10, 0], 14 | [1, 2, 3, 4, 5], 15 | [9, 8, 7, 2], 16 | [3], 17 | [] 18 | ] 19 | 20 | for elements in tests: 21 | insertion_sort(elements) 22 | print(f'Sorted array: {elements}') -------------------------------------------------------------------------------- /DSA-Python/linked_list.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, data=None, next=None): 3 | self.data = data 4 | self.next = next 5 | 6 | class LinkedList: 7 | def __init__(self): 8 | self.head = None 9 | 10 | def insert_at_beginning(self, data): 11 | node = Node(data, self.head) 12 | self.head = node 13 | 14 | def print(self): 15 | if(self.head is None): 16 | print("Linked List is empty.") 17 | return 18 | 19 | itr = self.head 20 | llstr = '' 21 | 22 | while(itr): 23 | llstr+= str(itr.data) + "-->" 24 | itr=itr.next 25 | 26 | print(llstr) 27 | 28 | def insert_at_end(self, data): 29 | if(self.head is None): 30 | self.head = Node(data, None) 31 | return 32 | itr = self.head 33 | while itr.next: 34 | itr = itr.next 35 | 36 | itr.next = Node(data, None) 37 | 38 | def insert_values(self, data_list): 39 | self.head = None 40 | for data in data_list: 41 | self.insert_at_end(data) 42 | 43 | def get_length(self): 44 | count = 0 45 | itr = self.head 46 | while itr: 47 | count += 1 48 | itr = itr.next 49 | 50 | return count 51 | 52 | def remove_at(self, index): 53 | if(index<0 or index>self.get_length()): 54 | raise Exception("Invalid index") 55 | 56 | if(index==0): 57 | self.head = self.head.next 58 | return 59 | 60 | count = 0 61 | itr = self.head 62 | while itr: 63 | if(count == index - 1): 64 | itr.next = itr.next.next 65 | break 66 | itr = itr.next 67 | count += 1 68 | 69 | def insert_at(self, index, data): 70 | if(index<0 or index>self.get_length()): 71 | raise Exception("Invalid index") 72 | 73 | if(index == 0): 74 | self.insert_at_beginning(data) 75 | return 76 | 77 | count = 0 78 | itr = self.head 79 | while itr: 80 | if(count == index - 1): 81 | node = Node(data, itr.next) 82 | itr.next = node 83 | break 84 | 85 | itr = itr.next 86 | count += 1 87 | 88 | def insert_after_value(self, data_after, data_to_insert): 89 | if self.head is None: 90 | return 91 | 92 | if self.head.data==data_after: 93 | self.head.next = Node(data_to_insert,self.head.next) 94 | return 95 | 96 | itr = self.head 97 | while itr: 98 | if(itr.data == data_after): 99 | node = Node(data_to_insert, itr.next) 100 | itr.next = node 101 | break 102 | itr = itr.next 103 | 104 | def remove_by_value(self, data): 105 | if self.head is None: 106 | return 107 | 108 | if self.head.data == data: 109 | self.head = self.head.next 110 | return 111 | 112 | itr = self.head 113 | while itr: 114 | if(itr.next.data == data): 115 | itr.next = itr.next.next 116 | break 117 | itr = itr.next 118 | 119 | 120 | 121 | if __name__ == '__main__': 122 | ll = LinkedList() 123 | #ll.insert_at_beginning(5) 124 | #ll.insert_at_beginning(89) 125 | #ll.insert_at_end(79) 126 | ll.insert_values(['bananas', 'grapes', 'apples', 'mangoes']) 127 | ll.print() 128 | print("Length:", ll.get_length()) 129 | ll.remove_at(2) 130 | ll.print() 131 | print("Length:", ll.get_length()) 132 | ll.insert_at(0, 'figs') 133 | ll.insert_at(2, 'jackfruits') 134 | ll.insert_after_value('figs', 'oranges') 135 | ll.print() 136 | ll.remove_by_value('grapes') 137 | ll.print() 138 | print("Length:", ll.get_length()) -------------------------------------------------------------------------------- /DSA-Python/merge_sort.py: -------------------------------------------------------------------------------- 1 | def merge_sort(arr): 2 | if len(arr) <= 1: 3 | return 4 | 5 | mid = len(arr)//2 6 | left = arr[:mid] 7 | right = arr[mid:] 8 | 9 | merge_sort(left) 10 | merge_sort(right) 11 | 12 | merge_two_sorted_lists(left, right, arr) 13 | 14 | def merge_two_sorted_lists(a, b, arr): 15 | len_a = len(a) 16 | len_b = len(b) 17 | i = j = k = 0 18 | 19 | while i < len_a and j < len_b: 20 | if a[i] <= b[j]: 21 | arr[k] = a[i] 22 | i += 1 23 | else: 24 | arr[k] = b[j] 25 | j += 1 26 | k += 1 27 | 28 | while i < len_a: 29 | arr[k] = a[i] 30 | i += 1 31 | k += 1 32 | while j < len_b: 33 | arr[k] = b[j] 34 | j += 1 35 | k += 1 36 | 37 | if __name__ == "__main__": 38 | tests = [ 39 | [10, 3, 15, 7, 8, 23, 98, 29], 40 | [25, 22, -1, 21, 10, 0], 41 | [1, 2, 3, 4, 5], 42 | [9, 8, 7, 2], 43 | [3], 44 | [] 45 | ] 46 | 47 | for elements in tests: 48 | merge_sort(elements) 49 | print(f'Sorted array: {elements}') -------------------------------------------------------------------------------- /DSA-Python/queue.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | class Queue: 4 | def __init__(self): 5 | self.buffer = deque() 6 | 7 | def enqueue(self, val): 8 | self.buffer.appendleft(val) 9 | 10 | def dequeue(self): 11 | return self.buffer.pop() 12 | 13 | def is_empty(self): 14 | return len(self.buffer)==0 15 | 16 | def size(self): 17 | return len(self.buffer) 18 | 19 | pq = Queue() 20 | 21 | pq.enqueue({ 22 | 'company': 'Wal Mart', 23 | 'timestamp': '15 Apr, 11.01 AM', 24 | 'price': 131.10 25 | }) 26 | 27 | pq.enqueue({ 28 | 'company': 'Wal Mart', 29 | 'timestamp': '15 Apr, 11.02 AM', 30 | 'price': 132 31 | }) 32 | 33 | pq.enqueue({ 34 | 'company': 'Wal Mart', 35 | 'timestamp': '15 Apr, 11.03 AM', 36 | 'price': 135 37 | }) 38 | 39 | print(pq.size()) 40 | 41 | print(pq.buffer) 42 | 43 | print(pq.dequeue()) 44 | 45 | print(pq.size()) 46 | 47 | print(pq.buffer) -------------------------------------------------------------------------------- /DSA-Python/quick_sort.py: -------------------------------------------------------------------------------- 1 | def swap(a, b, arr): 2 | if a!= b: 3 | tmp = arr[a] 4 | arr[a] = arr[b] 5 | arr[b] = tmp 6 | 7 | def partition(elements, start, end): 8 | pivot_index = start 9 | pivot = elements[pivot_index] 10 | 11 | while start < end: 12 | while start < len(elements) and elements[start] <= pivot: 13 | start += 1 14 | 15 | while elements[end] > pivot: 16 | end -= 1 17 | 18 | if start < end: 19 | swap(start, end, elements) 20 | 21 | swap(pivot_index, end, elements) 22 | 23 | return end 24 | 25 | def quick_sort(elements, start, end): 26 | if start < end: 27 | pi = partition(elements, start, end) 28 | 29 | quick_sort(elements, start, pi-1) # Left partition 30 | quick_sort(elements, pi+1, end) # Right partition 31 | 32 | if __name__ == "__main__": 33 | tests = [ 34 | [10, 3, 15, 7, 8, 23, 98, 29], 35 | [25, 22, -1, 21, 10, 0], 36 | [1, 2, 3, 4, 5], 37 | [9, 8, 7, 2], 38 | [3], 39 | [] 40 | ] 41 | 42 | for elements in tests: 43 | quick_sort(elements, 0, len(elements)-1) 44 | print(f'Sorted array: {elements}') -------------------------------------------------------------------------------- /DSA-Python/selection_sort.py: -------------------------------------------------------------------------------- 1 | def selection_sort(arr): 2 | size = len(arr) 3 | for i in range(size-1): 4 | min_index = i 5 | for j in range(min_index+1, size): 6 | if arr[j] < arr[min_index]: 7 | min_index = j 8 | 9 | if i != min_index: 10 | arr[i], arr[min_index] = arr[min_index], arr[i] 11 | 12 | if __name__ == "__main__": 13 | tests = [ 14 | [10, 3, 15, 7, 8, 23, 98, 29], 15 | [25, 22, -1, 21, 10, 0], 16 | [1, 2, 3, 4, 5], 17 | [9, 8, 7, 2], 18 | [3], 19 | [] 20 | ] 21 | 22 | for elements in tests: 23 | selection_sort(elements) 24 | print(f'Sorted array: {elements}') -------------------------------------------------------------------------------- /DSA-Python/shell_sort.py: -------------------------------------------------------------------------------- 1 | def shell_sort(arr): 2 | size = len(arr) 3 | gap = size//2 4 | 5 | while gap > 0: 6 | for i in range(gap, size): 7 | anchor = arr[i] 8 | j = i 9 | while j >= gap and arr[j-gap] > anchor: 10 | arr[j] = arr[j-gap] 11 | j -= gap 12 | arr[j] = anchor 13 | gap = gap//2 14 | 15 | if __name__ == "__main__": 16 | tests = [ 17 | [10, 3, 15, 7, 8, 23, 98, 29], 18 | [25, 22, -1, 21, 10, 0], 19 | [1, 2, 3, 4, 5], 20 | [9, 8, 7, 2], 21 | [3], 22 | [] 23 | ] 24 | 25 | for elements in tests: 26 | shell_sort(elements) 27 | print(f'Sorted array: {elements}') -------------------------------------------------------------------------------- /DSA-Python/stack.py: -------------------------------------------------------------------------------- 1 | # Stack follows LIFO 2 | 3 | from collections import deque 4 | 5 | class Stack(): 6 | def __init__(self): 7 | self.container = deque() 8 | 9 | def push(self, val): 10 | self.container.append(val) 11 | 12 | def pop(self): 13 | self.container.pop() 14 | 15 | def peek(self): 16 | if(self.is_empty()): 17 | return ("Stack is empty") 18 | else: 19 | return self.container[-1] 20 | 21 | def is_empty(self): 22 | return (len(self.container) == 0) 23 | 24 | def size(self): 25 | return len(self.container) 26 | 27 | s = Stack() 28 | 29 | s.push(5) 30 | print(s.peek()) 31 | s.pop() 32 | print(s.peek()) 33 | print(s.size()) 34 | s.push(67) 35 | s.push(2) 36 | s.push(5) 37 | print(s.peek()) 38 | print(s.size()) -------------------------------------------------------------------------------- /DSA-Python/tree.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, data): 3 | self.data = data 4 | self.children = [] 5 | self.parent = None 6 | 7 | def add_child(self, child): 8 | child.parent = self 9 | self.children.append(child) 10 | 11 | def get_level(self): 12 | level = 0 13 | p = self.parent 14 | while p: 15 | level += 1 16 | p = p.parent 17 | 18 | return level 19 | 20 | def print_tree(self): 21 | spaces = ' ' * self.get_level() * 3 22 | prefix = spaces + "|__" if self.parent else "" 23 | print(prefix + self.data) 24 | if(self.children): 25 | for child in self.children: 26 | child.print_tree() 27 | 28 | def build_product_tree(): 29 | root = TreeNode("Electronics") 30 | 31 | laptop = TreeNode("Laptop") 32 | laptop.add_child(TreeNode("Mac")) 33 | laptop.add_child(TreeNode("Surface")) 34 | laptop.add_child(TreeNode("Thinkpad")) 35 | 36 | cellphone = TreeNode("Cell Phone") 37 | cellphone.add_child(TreeNode("iPhone")) 38 | cellphone.add_child(TreeNode("Google Pixel")) 39 | cellphone.add_child(TreeNode("Vivo")) 40 | 41 | tv = TreeNode("TV") 42 | tv.add_child(TreeNode("Samsung")) 43 | tv.add_child(TreeNode("LG")) 44 | 45 | root.add_child(laptop) 46 | root.add_child(cellphone) 47 | root.add_child(tv) 48 | 49 | return root 50 | 51 | if __name__ == '__main__': 52 | root = build_product_tree() 53 | root.print_tree() 54 | pass -------------------------------------------------------------------------------- /DSA-Python/util.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | def time_it(func): 4 | def wrapper(*args, **kwargs): 5 | start = time.time() 6 | result = func(*args, **kwargs) 7 | end = time.time() 8 | print(func.__name__+" took " + str((end-start)*1000) + " mil sec") 9 | return result 10 | return wrapper -------------------------------------------------------------------------------- /DSA_Header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AakashBelide/DSA/d356b7859f43dacb4e30320ebc9ebec56fc0bdc3/DSA_Header.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![DSA](DSA_Header.png "DSA") 2 | - **You are never too late :clock12:.** Start your preparation as soon as possible to have an edge over others. 3 | 4 | - Try to start your preparation in your 2nd year itself as it can help crack the on-campus internships which have greater chances of getting converted to PPO and you can concentrate on other things during the placement season. 5 | 6 | - Try to do **minimum :three::five::zero:**+ questions (good quality). Preferably concentrate more on medium-level questions. Be consistent and solve questions every day. 7 | 8 | - Be thorough in at least **:one:** language (C++ or Java or Python). If you are going ahead with Python, try to have a backup language (either C++ or Java) in which you know the basics of coding as some companies do not allow Python but it is very rare. The main reason is that many codes might give TLE in Python and the same code in other languages would work perfectly. **I have added few codes in Python as I could not find a single place where the solutions for various questions are in Python. I will try to add more solutions in the future.** 9 | 10 | - Make sure you know Java and C++ to understand the basic syntax as many technical MCQs are based on these languages. 11 | 12 | - If possible, do the daily problems on [Leetcode](https://leetcode.com/explore/featured/card/august-leetcoding-challenge-2021/) and [GFG](https://practice.geeksforgeeks.org/problem-of-the-day). 13 | 14 | - Have a clear idea if you want to pursue masters or sit for placements if your university doesn't allow you to reject on-campus offers. 15 | 16 | - Know and adhere to all the rules of your campus placement cell to avoid getting into trouble. 17 | 18 | - Make a habit of checking your emails from time to time. If you miss out on an important mail, you may regret it later. 19 | 20 | - Talk to like-minded people and share resources with each other. **Don't be greedy :x:.** 21 | 22 | - Try to make a group with friends who solve questions consistently. Discuss your solutions with each other to understand various approaches for the same question. 23 | 24 | - The placement season can be very stressful. You might face many rejections but don't give up. Try to have enough sleep and balance everything else as well. **Luck matters a lot during placements**. 25 | 26 | - Your **CGPA** matters a lot for getting shortlisted. Once you are shortlisted, give it your all to clear the coding and interview rounds. 27 | 28 | :large_blue_circle:*Note: Other tips on technical and management-related placements and higher studies (Masters) would be added in the future.* 29 | 30 | ## Data Structures and Algorithms to practice :triangular_flag_on_post: 31 | - Arrays 32 | - Linked List 33 | - Stack 34 | - Hashing 35 | - Queue 36 | - Strings 37 | - Bit Magic 38 | - Sorting (Various algorithms) 39 | - Searching (Binary Search - important) 40 | - Sliding Window 41 | - 2 or n-pointer approaches 42 | - Backtracking 43 | - Greedy 44 | - Trees (Binary Trees, BST) 45 | - Heaps 46 | - Recursion (Do this before DP) 47 | - DP (For Top Companies) 48 | - Graphs (For Top Companies) 49 | 50 | 51 | ## Resources :memo: 52 | ### Sheets and Quality Questions :green_book: 53 | - [Love Babbar - DSA 450 Sheet](https://drive.google.com/file/d/1FMdN_OCfOI0iAeDlqswCiC2DZzD4nPsb/view) | [DSA 450 Tracker](https://450-dsa-tracker.netlify.app/) | [450DSA](https://450dsa.com/) 54 | - [Striver - SDE Sheet](https://docs.google.com/document/d/1SM92efk8oDl8nyVw8NHPnbGexTS9W-1gmTEYfEurLWQ/preview?pru=AAABe4GAo70*4StOWEVxAxVhQj02RA1FhA) 55 | 56 | - [GFG Must Do Interview Preparation Questions](https://practice.geeksforgeeks.org/courses/must-do-interview-prep?vC=1) 57 | 58 | - [Leetcode Top Interview Questions - Easy, Medium & Hard](https://leetcode.com/explore/interview/card/top-interview-questions-easy/) 59 | 60 | - [CSES Competitive Programmer’s Handbook](https://cses.fi/book/book.pdf) 61 | 62 | - [Extra Resources](https://anubhavsinha98.medium.com/resources-to-master-data-structures-and-algorithms-24450dc6d52b) 63 | 64 | 65 | ### Youtube :tv: 66 | - [Aditya Verma](https://www.youtube.com/channel/UC5WO7o71wvxMxEtLRkPhiQQ) - DP and Recursion (His other playlists are good as well) 67 | 68 | - [Striver](https://www.youtube.com/channel/UCJskGeByzRRSvmOyZOz61ig) - SDE Sheet solutions (Graphs and other playlists are good as well) 69 | 70 | - [Anuj Bhaiya](https://www.youtube.com/playlist?list=PLUcsbZa0qzu3yNzzAxgvSgRobdUUJvz7p) - The DSA One Course (Good DSA Videos, his other playlists are too helpful) 71 | 72 | - [GFG Data Structures and Algorithms Course](https://practice.geeksforgeeks.org/courses/dsa-self-paced) (Buy it only if you can afford it. Covers most of the basic foundations and is worth the money :heavy_dollar_sign:. You can do well with online free resources as well.) 73 | 74 | - [Codebasics - Python 3 Programming Tutorials for Beginners](https://youtube.com/playlist?list=PLeo1K3hjS3uv5U-Lmlnucd7gqF-3ehIh0) 75 | 76 | 77 | ## Platforms :key: 78 | Do check out the solutions, editorials, and discussion once you solve or cannot solve the problem to understand the various approaches. 79 | - [Hackerrank](https://www.hackerrank.com/) (Basics) 80 | - [GFG](https://practice.geeksforgeeks.org/explore/?company%5B%5D=Amazon&problemType=functional&page=1&sortBy=submissions&company%5B%5D=Amazon) (Medium to Advanced) - Recomended 81 | - [Leetcode](https://leetcode.com/explore/) (Medium to Advanced) - Recomended 82 | - [CSES Problem Set](https://cses.fi/problemset/) (Medium to Advanced) 83 | - [Codechef](https://www.codechef.com/) (Advanced) 84 | - [CodeForces](https://codeforces.com/) (Advanced) 85 | 86 | 87 | 88 | ## Theory (Interview POV and Practice Resources) :notebook: 89 | GFG Last Minute Notes are more theoretical and contain only text generally. I prefer Interviewbit as they have both textual and pictorial representation which is better for understanding. 90 | 91 | Try to cover all the resources for each theory topic. 92 | 93 | If you have enough time, check out the interview questions based on your domain on Interviewbit. They have interview questions for Data Science, Machine Learning, Cloud, Node, etc. which can be helpful. 94 | 95 | If you want extra questions or resources, check out: [Striver Code Sheet](https://docs.google.com/document/d/1sQlRDw6--HwyxeFL7b4kBsOG-Tz7rXMbpWNnfvJErA4/edit) or [Love Babbar Roadmaps](https://youtube.com/playlist?list=PL4PCksYQGLJMtEI_0y0FWf3dz1DzB_2KU) 96 | 97 | ### DBMS :minidisc: 98 | To practice SQL questions, you can try [Leetcode Database Problems](https://leetcode.com/problemset/database/?page=1) and [HackerRank](https://www.hackerrank.com/domains/sql) 99 | 100 |
101 | Tips and resources: 102 | 125 |
126 | 127 |
128 | 129 | - [GFG LMS](https://www.geeksforgeeks.org/last-minute-notes-dbms/) 130 | - [Interviewbit](https://www.interviewbit.com/dbms-interview-questions/) 131 | - [Interviewbit - SQL](https://www.interviewbit.com/sql-interview-questions/#questions) 132 | - [Javatpoint](https://www.javatpoint.com/sql-interview-questions) 133 | 134 | ### OOPS :closed_lock_with_key: 135 | **Note: OOPs concepts differ from language to language.** 136 | 137 |
138 | Tips and resources: 139 | 163 |
164 | 165 |
166 | 167 | - [Interviewbit](https://www.interviewbit.com/oops-interview-questions/) 168 | - [Javatpoint](https://www.javatpoint.com/oops-interview-questions) 169 | 170 | ### OS :computer: 171 | - [GFG LMS](https://www.geeksforgeeks.org/last-minute-notes-operating-systems/) 172 | - [Interviewbit](https://www.interviewbit.com/operating-system-interview-questions/) 173 | - [Javatpoint](https://www.javatpoint.com/operating-system-interview-questions) 174 | 175 | ### Networking :e-mail: 176 | - [GFG LMS](https://www.geeksforgeeks.org/last-minute-notes-computer-network/) 177 | - [Interviewbit](https://www.interviewbit.com/networking-interview-questions/) 178 | - [Javatpoint](https://www.javatpoint.com/networking-interview-questions) 179 | 180 | 181 | ## Aptitude :bar_chart: 182 | - [IndiaBix](https://www.indiabix.com/) - Recomended (Go through the important formulas for each topic) 183 | - [CareerRide](https://www.youtube.com/playlist?list=PLpyc33gOcbVA4qXMoQ5vmhefTruk5t9lt) - Solve types of questions and make a formula sheet 184 | - [Coding Ninjas](https://www.codingninjas.com/codestudio/guided-paths/aptitude-preparation) 185 | 186 | ## Reasoning :brain: 187 | - [CareerRide](https://www.youtube.com/playlist?list=PLpyc33gOcbVADMKqylI__O_O_RMeHTyNK) 188 | - [IndiaBix](https://www.indiabix.com/logical-reasoning/questions-and-answers/) 189 | 190 | ## Puzzles :trophy: 191 | - [Normal (GFG)](https://www.geeksforgeeks.org/puzzles/) 192 | - Guesstimates 193 | 194 | ## Interview Tips :clipboard: 195 | - Read interview experiences from GFG or elsewhere before every test or interview as the questions repeat sometimes and you will have a rough idea which will narrow down on the topics to prepare. 196 | 197 | - If you know about your interview panel, check out their profiles on LinkedIn (anonymously) and concentrate more on the projects which clash with their domain of expertise as they can go deep while asking questions. 198 | 199 | - While answering any DSA problem during an interview, start with the brute force approach and eventually optimize your code even if you know the optimized approach. Don't waste much time on brute force if you already know the best approach. 200 | 201 | - Don't act if you don't know the answer to any question. 202 | 203 | - Be confident while answering and keep smiling throughout the interview. 204 | 205 | - Prepare a short introduction about yourself which can be told in 1 or 2 minutes. Be prepared with this because if you think during the interview it would leave a bad impression. 206 | 207 | - Make sure you start and end the interview on a good note. Thank the interviewer(s) at the end. 208 | 209 | - Know the basic things for the managerial or HR round like about the company, why do you want to join them, how would you contribute, your future aim, situational questions. Try to be genuine and natural. 210 | 211 | - Dress up properly. 212 | 213 |
214 | Resume 215 |
    216 |
  • Work properly a day or two on your resume.
  • 217 |
  • Make sure your resume is in either PDF or Word Dcoument format and the text can be copied by dragging (The text cannot be copied if your resume is an image if you make it in photoshop).
  • 218 |
  • Mention projects and attach a link if it is hosted or has a github repo.
  • 219 |
  • Proof Read
  • 220 |
  • Don't mention unnecessary stuff. Mention only those skills and projects which you actually know.
  • 221 |
  • Don't worry if you have a mediocre resume, concentrate more on your preparation.
  • 222 |
  • If you have done any internship(s) then that's good, else it is fine. Won't matter in an interview if you can answer everything.
  • 223 |
  • You can use Resume Worded for better resume making tips.
  • 224 |
  • You can use Overleaf or Canva for making your resume.
  • 225 |
226 |
227 | 228 |
229 | 230 |
231 | Projects 232 |
    233 |
  • Try to make unique projects.
  • 234 |
  • Host your projects if possible.
  • 235 |
  • Be thorough with all the concepts in your project.
  • 236 |
  • Go through your projects and make sure they are working prior to your interviews.
  • 237 |
238 |
239 | 240 |
241 | 242 | # Contributors :fire: 243 | - [Belide Aakash](https://www.linkedin.com/in/belideaakash/) 244 | - [Amanpreet Taluja](https://www.linkedin.com/in/amanpreet-taluja-a14822216/) 245 | - [Apnik Jain](https://www.linkedin.com/in/apnik-jain/) 246 | - [Umang Agarwal](https://www.linkedin.com/in/umang-agarwal-5b227617b) 247 | 248 |
249 | 250 | Other Contributors: 251 | - [Sarthak Verma](https://linkedin.com/in/sarthakv/) - DSA450 Extra tracker and DSA Playlist 252 | - [Mihir Bhasin](https://www.linkedin.com/in/mihir-bhasin-3906bb185) - Extra resources for aptitude and reasoning 253 | 254 | **:red_circle:Note: All the above-mentioned tips are based on our personal views and experiences. This is just to help you out with your preparation and doesn't guarantee that you will be placed. We are not responsible for anything.** 255 | 256 | Star :star: this repo if you like it. 257 | 258 |

Good luck with your preparation 👍 259 |

260 | -------------------------------------------------------------------------------- /Recursion/basic1.py: -------------------------------------------------------------------------------- 1 | #printing 1 to N, N to 1 and factorial of N using recusrion 2 | 3 | n = int(input("Enter the number: ")) 4 | 5 | #printing 1 to N using recusrion 6 | def oneton(a): 7 | if (a == 1): 8 | print(a) 9 | return 10 | oneton(a-1) 11 | print(a) 12 | 13 | #printing N to 1 using recusrion 14 | def ntoone(b): 15 | if (b == 1): 16 | print(b) 17 | return 18 | print(b) 19 | ntoone(b-1) 20 | 21 | #printing factorial of N using recusrion 22 | def fact(c): 23 | if (c == 0 or c == 1): 24 | return 1 25 | return (c*fact(c-1)) 26 | 27 | print(fact(n)) -------------------------------------------------------------------------------- /Recursion/basic2.py: -------------------------------------------------------------------------------- 1 | #sorting an array using recursion only 2 | 3 | v = [int(i) for i in input("Enter the list/array elements with spaces between each of them: ").split()] 4 | 5 | 6 | def insrt(a, b): 7 | if (len(a) == 0 or a[-1]<=b): 8 | a.append(b) 9 | return 10 | c = a.pop() 11 | insrt(a, b) 12 | a.append(c) 13 | return a 14 | 15 | def srt(x): 16 | if (len(x) == 1): 17 | return 18 | y = x.pop() 19 | srt(x) 20 | insrt(x, y) 21 | return x 22 | 23 | print(srt(v)) -------------------------------------------------------------------------------- /Recursion/basic3.py: -------------------------------------------------------------------------------- 1 | #Deleting middle element in a stack using recursion 2 | 3 | s = [int(i) for i in input("Enter the stack elements with spaces between each of them: ").split()] 4 | l = len(s) 5 | def delmid(a, b): 6 | if (b == 0): 7 | return a 8 | 9 | k = ((b/2) + 1) 10 | """ 11 | if (b%2 == 0): 12 | k = ((b/2) + 1) 13 | else: 14 | k = ((b+1)/2) 15 | """ 16 | solve(a, int(k)) 17 | return a 18 | 19 | def solve(c, d): 20 | if (d == 1): 21 | c.pop() 22 | return 23 | 24 | temp = c.pop() 25 | solve(c, d-1) 26 | c.append(temp) 27 | return 28 | 29 | print(delmid(s,l)) -------------------------------------------------------------------------------- /Recursion/basic4.py: -------------------------------------------------------------------------------- 1 | #Reverse a stack using recursion 2 | 3 | s = [int(i) for i in input("Enter the stack elements with spaces between each of them: ").split()] 4 | 5 | def rev(a): 6 | if (len(a) == 1): 7 | return 8 | 9 | b = a.pop() 10 | rev(a) 11 | ins(a, b) 12 | return a 13 | 14 | def ins(c, d): 15 | if (len(c) == 0): 16 | c.append(d) 17 | return 18 | 19 | e = c.pop() 20 | ins(c, d) 21 | c.append(e) 22 | return 23 | 24 | print(rev(s)) -------------------------------------------------------------------------------- /Recursion/hard1.py: -------------------------------------------------------------------------------- 1 | #Print N-bit binary numbers having more 1’s than 0’s for any prefix 2 | 3 | n = int(input("Enter number: ")) 4 | 5 | o = 0 6 | c = 0 7 | op = "" 8 | a = [] 9 | 10 | #Own logic 11 | def sol(v, w, x , y, z): 12 | if (v == 0): 13 | z.append(y) 14 | return 15 | 16 | if (w > x): 17 | y1 = y + "0" 18 | y2 = y + "1" 19 | sol(v-1,w,x+1,y1,z) 20 | sol(v-1,w+1,x,y2,z) 21 | 22 | if (w == x): 23 | y += "1" 24 | sol(v-1,w+1,x,y,z) 25 | 26 | return 27 | 28 | #Tutorial logic 29 | def sol_l(v, w, x , y, z): 30 | if (v == 0): 31 | z.append(y) 32 | return 33 | 34 | y1 = y + "1" 35 | sol(v-1,w+1,x,y1,z) 36 | 37 | if (w > x): 38 | y2 = y + "0" 39 | sol(v-1,w,x+1,y2,z) 40 | return 41 | 42 | sol_l(n, o, c, op, a) 43 | print(a) -------------------------------------------------------------------------------- /Recursion/hard2.py: -------------------------------------------------------------------------------- 1 | #Josephus Problem | Game of Death in a circle | Execution in Circle 2 | 3 | 4 | #The total number of people present 5 | n = [int(i) for i in range(1, int(input("Enter number of people: ")) + 1)] 6 | #The number of people to skip after killing each person 7 | k = int(input("Number of people to skip to kill: ")) 8 | k = k - 1 9 | ind = 0 10 | 11 | def sol(a, b, c): 12 | if (len(a) == 1): 13 | print(a[0]) 14 | return 15 | print(a, b, c) 16 | c = (c + b) % len(a) 17 | a.remove(a[c]) 18 | sol(a, b, c) 19 | 20 | sol(n, k, ind) 21 | -------------------------------------------------------------------------------- /Recursion/medium1.py: -------------------------------------------------------------------------------- 1 | #Kth symbol in grammar (recursion) 2 | import sys 3 | sys.setrecursionlimit(10**6) 4 | 5 | a = int(input("Enter first digit (N): ")) 6 | b = int(input("Enter second digit (K): ")) 7 | 8 | def kthGrammar(N, K): 9 | if (N == 1 and K == 1): 10 | return 0 11 | mid = (2**(N-1))/2 12 | if K<=mid: 13 | return kthGrammar(N-1,K) 14 | else: 15 | ans = kthGrammar(N-1,K-mid) 16 | if(ans == 0): 17 | return 1 18 | else: 19 | return 0 20 | 21 | #From leetcode discussion 22 | def kthGrammar2(N, K): 23 | if (N == 1): 24 | return 0 25 | else: 26 | if K%2: 27 | return kthGrammar2(N-1,(K-1)//2+1) 28 | else: 29 | return 1-kthGrammar2(N-1,(K-1)//2+1) 30 | 31 | print(kthGrammar(a, b)) 32 | print(kthGrammar2(a, b)) -------------------------------------------------------------------------------- /Recursion/medium2.py: -------------------------------------------------------------------------------- 1 | #Tower of Hanoi with each step printed along with number of steps printed 2 | 3 | n = int(input("Enter your number: ")) 4 | count = 0 5 | x = "Source" 6 | y = "Auxillary" 7 | z = "Destination" 8 | def sol(m, s, d, h, c): 9 | if (m == 1): 10 | print("Moved plate " + str(m) + " from " + s + " to " + d) 11 | c+=1 12 | return c 13 | 14 | sol(m-1, s, h, d, c) 15 | print("Moved plate " + str(m) + " from " + s + " to " + d) 16 | c+=1 17 | sol(m-1, h, d, s, c) 18 | return c 19 | 20 | print(sol(n, x, z, y, count)) -------------------------------------------------------------------------------- /Recursion/medium3.py: -------------------------------------------------------------------------------- 1 | #Printing all the subsets of a string using recursion 2 | 3 | ip = input("Enter the string you want subsets for: ") 4 | op = "" 5 | x = [] 6 | 7 | def solve(a, b): 8 | if (len(a) == 0): 9 | x.append(b) 10 | return 11 | else: 12 | b1 = b 13 | b2 = b 14 | b2 = b2 + a[0] 15 | a = a[1:] 16 | solve(a, b1) 17 | solve(a, b2) 18 | return 19 | 20 | solve(ip, op) 21 | x.sort() 22 | print(x) -------------------------------------------------------------------------------- /Recursion/medium4.py: -------------------------------------------------------------------------------- 1 | #Permutations with spaces 2 | 3 | ip = input("Enter the string you want permutations with spaces for: ") 4 | op = "" 5 | op = ip[0] 6 | ip = ip[1:] 7 | x = [] 8 | 9 | def solve(a, b): 10 | if (len(a) == 0): 11 | x.append(b) 12 | return 13 | else: 14 | b1 = b 15 | b2 = b 16 | b1 = b1 + " " + a[0] 17 | b2 = b2 + a[0] 18 | a = a[1:] 19 | solve(a, b1) 20 | solve(a, b2) 21 | return 22 | 23 | solve(ip, op) 24 | x.sort() 25 | print(x) -------------------------------------------------------------------------------- /Recursion/medium5.py: -------------------------------------------------------------------------------- 1 | #Permutations with case change 2 | 3 | ip1 = input("Enter the lower case string: ") 4 | ip2 = input("Enter the upper case string: ") 5 | ip3 = input("Enter the any case string: ") 6 | op = "" 7 | x = [] 8 | y = [] 9 | z = [] 10 | #For only lower case input 11 | def solve1(a, b, c): 12 | if (len(a) == 0): 13 | c.append(b) 14 | return 15 | else: 16 | b1 = b 17 | b2 = b 18 | b1 = b1 + a[0].upper() 19 | b2 = b2 + a[0] 20 | a = a[1:] 21 | solve1(a, b1, c) 22 | solve1(a, b2, c) 23 | return 24 | 25 | #For only upper case input 26 | def solve2(a, b, c): 27 | if (len(a) == 0): 28 | c.append(b) 29 | return 30 | else: 31 | b1 = b 32 | b2 = b 33 | b1 = b1 + a[0].lower() 34 | b2 = b2 + a[0] 35 | a = a[1:] 36 | solve2(a, b1, c) 37 | solve2(a, b2, c) 38 | return 39 | 40 | #For any case input 41 | def solve3(a, b, c): 42 | if (len(a) == 0): 43 | c.append(b) 44 | return 45 | else: 46 | b1 = b 47 | b2 = b 48 | if a[0].islower(): 49 | b1 = b1 + a[0].upper() 50 | b2 = b2 + a[0].lower() 51 | else: 52 | b1 = b1 + a[0].lower() 53 | b2 = b2 + a[0].upper() 54 | a = a[1:] 55 | solve3(a, b1, c) 56 | solve3(a, b2, c) 57 | return 58 | 59 | solve1(ip1, op, x) 60 | solve2(ip2, op, y) 61 | solve3(ip3, op, z) 62 | print(x) 63 | print(y) 64 | print(z) -------------------------------------------------------------------------------- /Recursion/medium6.py: -------------------------------------------------------------------------------- 1 | #Letter case change 2 | 3 | ip = input("Enter the string you want permutations with spaces for: ") 4 | op = "" 5 | x = [] 6 | 7 | def solve(a, b, c): 8 | if (len(a) == 0): 9 | c.append(b) 10 | return 11 | 12 | if a[0].isalpha(): 13 | b1 = b 14 | b2 = b 15 | b1 = b1 + a[0].lower() 16 | b2 = b2 + a[0].upper() 17 | a = a[1:] 18 | solve(a, b1, c) 19 | solve(a, b2, c) 20 | return 21 | else: 22 | b = b + a[0] 23 | a = a[1:] 24 | solve(a, b, c) 25 | return 26 | 27 | 28 | solve(ip, op, x) 29 | print(x) -------------------------------------------------------------------------------- /Recursion/medium7.py: -------------------------------------------------------------------------------- 1 | #Generate all balanced Parentheses 2 | 3 | n = int(input("Enter number: ")) 4 | 5 | o = n 6 | c = n 7 | op = "" 8 | a = [] 9 | 10 | 11 | def sol(w, x , y, z): 12 | if (w==0 and x ==0): 13 | z.append(y) 14 | return 15 | 16 | if (w!=0): 17 | op1 = y 18 | op1 += "(" 19 | sol(w-1, x, op1, z) 20 | 21 | if (x > w): 22 | op2 = y 23 | op2 += ")" 24 | sol(w, x-1, op2, z) 25 | 26 | return 27 | 28 | sol(o, c, op, a) 29 | 30 | print(a) -------------------------------------------------------------------------------- /Recursion/minion.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | s = "BANANA" 4 | vowels = "AEIUO" 5 | a = "Stuart" 6 | st = [] 7 | a1 = 0 8 | b = "Kevin" 9 | kv = [] 10 | b1 = 0 11 | x = [] 12 | sop = "" 13 | 14 | def solve(a, b): 15 | if (len(a) == 0): 16 | x.append(b) 17 | return 18 | else: 19 | b1 = b 20 | b2 = b 21 | b2 = b2 + a[0] 22 | a = a[1:] 23 | solve(a, b1) 24 | solve(a, b2) 25 | return 26 | 27 | solve(s, sop) 28 | 29 | def CountOccurrences(string, substring): 30 | 31 | # Initialize count and start to 0 32 | count = 0 33 | start = 0 34 | 35 | # Search through the string till 36 | # we reach the end of it 37 | while start < len(string): 38 | 39 | # Check if a substring is present from 40 | # 'start' position till the end 41 | pos = string.find(substring, start) 42 | 43 | if pos != -1: 44 | # If a substring is present, move 'start' to 45 | # the next position from start of the substring 46 | start = pos + 1 47 | 48 | # Increment the count 49 | count += 1 50 | else: 51 | # If no further substring is present 52 | break 53 | # return the value of count 54 | return count 55 | 56 | for i in range(len(x)): 57 | if(x[i]!="" and x[i] not in st and x[i][0] not in vowels): 58 | st.append(x[i]) 59 | elif(x[i]!="" and x[i] not in kv and x[i][0] in vowels): 60 | kv.append(x[i]) 61 | 62 | for j in st: 63 | ssc = CountOccurrences(s, j) 64 | a1 += ssc 65 | 66 | for k in kv: 67 | ksc = CountOccurrences(s,k) 68 | b1 += ksc 69 | if(a1>b1): 70 | print(a + " " + str(a1)) 71 | elif(a1= min_ele): 14 | s.append(el) 15 | else: 16 | s.append(2*el - min_ele) 17 | min_ele = el 18 | 19 | def pop(s, min_ele): 20 | if(len(s) == 0): 21 | return -1 22 | if(s[-1] < min_ele): 23 | min_ele = 2*min_ele - s[-1] 24 | s.pop() 25 | 26 | def top(s, min_ele): 27 | if(len(s) == 0): 28 | return -1 29 | if(s[-1] < min_ele): 30 | return min_ele 31 | else: 32 | return s[-1] 33 | 34 | def min_el(min_ele): 35 | return min_ele -------------------------------------------------------------------------------- /Stack/2_nextgrtright.py: -------------------------------------------------------------------------------- 1 | # 2 NGR | Nearest Greater to right | Next Largest Element 2 | # https://practice.geeksforgeeks.org/problems/next-larger-element-1587115620/1 3 | # https://leetcode.com/problems/next-greater-element-i/ (Similar - Extension) 4 | 5 | arr = [1, 3, 2, 4] 6 | 7 | stack = [] 8 | 9 | ans = [] 10 | 11 | for i in range(len(arr)-1, -1, -1): 12 | if(len(stack) == 0): 13 | ans.append(-1) 14 | elif(stack[-1]>arr[i]): 15 | ans.append(stack[-1]) 16 | else: 17 | while(len(stack)>0 and stack[-1]arr[i]): 13 | ans.append(stack[-1]) 14 | else: 15 | while(len(stack)>0 and stack[-1]0 and stack[-1]>arr[i]): 16 | stack.pop() 17 | if(len(stack) == 0): 18 | ans.append(-1) 19 | else: 20 | ans.append(stack[-1]) 21 | stack.append(arr[i]) 22 | 23 | print(ans) -------------------------------------------------------------------------------- /Stack/5_nearsmlright.py: -------------------------------------------------------------------------------- 1 | # 5 NSR | Nearest Smaller to Right 2 | # https://www.geeksforgeeks.org/next-smaller-element/ 3 | 4 | arr = [4, 5, 2, 10, 8] 5 | 6 | stack = [] 7 | 8 | ans = [] 9 | 10 | for i in range(len(arr)-1, -1, -1): 11 | if(len(stack) == 0): 12 | ans.append(-1) 13 | elif(stack[-1]0 and stack[-1]>arr[i]): 17 | stack.pop() 18 | if(len(stack) == 0): 19 | ans.append(-1) 20 | else: 21 | ans.append(stack[-1]) 22 | stack.append(arr[i]) 23 | ans.reverse() 24 | print(ans) -------------------------------------------------------------------------------- /Stack/6_stockspan.py: -------------------------------------------------------------------------------- 1 | # 6 Stock Span Problem 2 | # https://practice.geeksforgeeks.org/problems/stock-span-problem-1587115621/1 3 | 4 | arr = [100, 80, 60, 70, 60, 75, 85] 5 | 6 | stack = [] 7 | 8 | ans = [] 9 | 10 | for i in range(len(arr)): 11 | if(len(stack) == 0): 12 | ans.append(-1) 13 | elif(stack[-1][0]>arr[i]): 14 | ans.append(stack[-1][1]) 15 | else: 16 | while(len(stack)>0 and stack[-1][0]<=arr[i]): 17 | stack.pop() 18 | if(len(stack) == 0): 19 | ans.append(-1) 20 | else: 21 | ans.append(stack[-1][1]) 22 | stack.append([arr[i], i]) 23 | 24 | for i in range(len(ans)): 25 | ans[i] = i - ans[i] 26 | 27 | """ No need of extra iteration 28 | for i in range(len(arr)): 29 | if(len(stack) == 0): 30 | ans.append(i + 1) 31 | elif(stack[-1][0]>arr[i]): 32 | ans.append(i - stack[-1][1]) 33 | else: 34 | while(len(stack)>0 and stack[-1][0]<=arr[i]): 35 | stack.pop() 36 | if(len(stack) == 0): 37 | ans.append(i+1) 38 | else: 39 | ans.append(i - stack[-1][1]) 40 | stack.append([arr[i], i])""" 41 | 42 | print(ans) -------------------------------------------------------------------------------- /Stack/7_maxarhist.py: -------------------------------------------------------------------------------- 1 | # 7 Maximum Area Histogram | MAH 2 | # https://practice.geeksforgeeks.org/problems/maximum-rectangular-area-in-a-histogram-1587115620/1# (TLE) 3 | # https://leetcode.com/problems/largest-rectangle-in-histogram/submissions/ 4 | 5 | arr = [6, 2, 5, 4, 5, 1, 6] 6 | 7 | # Left traversal 8 | stack = [] 9 | 10 | left = [] 11 | 12 | for i in range(len(arr)): 13 | if(len(stack) == 0): 14 | left.append(-1) 15 | elif(stack[-1][0]0 and stack[-1][0]>=arr[i]): 19 | stack.pop() 20 | if(len(stack) == 0): 21 | left.append(-1) 22 | else: 23 | left.append(stack[-1][1]) 24 | stack.append([arr[i], i]) 25 | 26 | # Right traversal 27 | stack = [] 28 | 29 | right = [] 30 | 31 | for i in range(len(arr)-1, -1, -1): 32 | if(len(stack) == 0): 33 | right.append(len(arr)) 34 | elif(stack[-1][0]0 and stack[-1][0]>=arr[i]): 38 | stack.pop() 39 | if(len(stack) == 0): 40 | right.append(len(arr)) 41 | else: 42 | right.append(stack[-1][1]) 43 | stack.append([arr[i], i]) 44 | right.reverse() 45 | 46 | ans = 0 47 | 48 | for i in range(len(arr)): 49 | tmp = right[i] - left[i] - 1 50 | ans = max(ans, tmp*arr[i]) 51 | 52 | # print(left) 53 | # print(right) 54 | 55 | print(ans) -------------------------------------------------------------------------------- /Stack/8_maxarbinmatrix.py: -------------------------------------------------------------------------------- 1 | # 8 Max Area Rectangle in binary matrix 2 | # https://practice.geeksforgeeks.org/problems/max-rectangle/1# (TLE) 3 | 4 | mat = [[0, 1, 1, 0], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 0, 0]] 5 | 6 | def mah(arr): 7 | # Left traversal 8 | stack = [] 9 | 10 | left = [] 11 | 12 | for i in range(len(arr)): 13 | if(len(stack) == 0): 14 | left.append(-1) 15 | elif(stack[-1][0]0 and stack[-1][0]>=arr[i]): 19 | stack.pop() 20 | if(len(stack) == 0): 21 | left.append(-1) 22 | else: 23 | left.append(stack[-1][1]) 24 | stack.append([arr[i], i]) 25 | 26 | # Right traversal 27 | stack = [] 28 | 29 | right = [] 30 | 31 | for i in range(len(arr)-1, -1, -1): 32 | if(len(stack) == 0): 33 | right.append(len(arr)) 34 | elif(stack[-1][0]0 and stack[-1][0]>=arr[i]): 38 | stack.pop() 39 | if(len(stack) == 0): 40 | right.append(len(arr)) 41 | else: 42 | right.append(stack[-1][1]) 43 | stack.append([arr[i], i]) 44 | right.reverse() 45 | 46 | ans = 0 47 | 48 | for i in range(len(arr)): 49 | tmp = right[i] - left[i] - 1 50 | ans = max(ans, tmp*arr[i]) 51 | 52 | return ans 53 | 54 | stck = [] 55 | 56 | for j in range(len(mat)): 57 | stck.append(mat[0][j]) 58 | 59 | mx = mah(stck) 60 | 61 | for i in range(1, len(mat)): 62 | for j in range(len(mat[i])): 63 | if(mat[i][j] == 0): 64 | stck[j] = 0 65 | else: 66 | stck[j] += mat[i][j] 67 | mx = max(mx, mah(stck)) 68 | 69 | print(mx) 70 | -------------------------------------------------------------------------------- /Stack/9_rainwatertrap.py: -------------------------------------------------------------------------------- 1 | # 9 Rain Water Trapping 2 | # https://practice.geeksforgeeks.org/problems/trapping-rain-water-1587115621/1 3 | # https://leetcode.com/problems/trapping-rain-water/ 4 | 5 | arr = [3, 0, 0, 2, 0, 4] 6 | 7 | l2r = [] 8 | l2r.append(arr[0]) 9 | 10 | r2l = [] 11 | r2l.append(arr[-1]) 12 | 13 | n = len(arr) 14 | 15 | for i in range(1, n): 16 | l2r.append(max(l2r[i-1], arr[i])) 17 | 18 | j = 0 19 | 20 | for i in range(n-2, -1, -1): 21 | r2l.append(max(r2l[j], arr[i])) 22 | j += 1 23 | 24 | r2l.reverse() 25 | 26 | amount = 0 27 | 28 | for i in range(n): 29 | amount += min(l2r[i], r2l[i]) - arr[i] 30 | 31 | print(amount) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/10_countinv.py: -------------------------------------------------------------------------------- 1 | # Inversion of Array (Using Merge Sort) 2 | # https://practice.geeksforgeeks.org/problems/inversion-of-array-1587115620/1# 3 | 4 | # Time Complexity: O(nlogn), Space Complexity: O(n) 5 | 6 | arr = [2, 4, 1, 3, 5] 7 | n = len(arr) 8 | 9 | def mergeSort(arr, n): 10 | def _mergeSort(arr, temp_arr, left, right): 11 | 12 | inv_count = 0 13 | 14 | if left < right: 15 | mid = (left + right)//2 16 | inv_count += _mergeSort(arr, temp_arr, left, mid) 17 | inv_count += _mergeSort(arr, temp_arr, mid + 1, right) 18 | inv_count += merge(arr, temp_arr, left, mid, right) 19 | return inv_count 20 | def merge(arr, temp_arr, left, mid, right): 21 | i = left 22 | j = mid + 1 23 | k = left 24 | inv_count = 0 25 | while i <= mid and j <= right: 26 | if arr[i] <= arr[j]: 27 | temp_arr[k] = arr[i] 28 | k += 1 29 | i += 1 30 | else: 31 | temp_arr[k] = arr[j] 32 | inv_count += (mid-i + 1) 33 | k += 1 34 | j += 1 35 | while i <= mid: 36 | temp_arr[k] = arr[i] 37 | k += 1 38 | i += 1 39 | while j <= right: 40 | temp_arr[k] = arr[j] 41 | k += 1 42 | j += 1 43 | for loop_var in range(left, right + 1): 44 | arr[loop_var] = temp_arr[loop_var] 45 | 46 | return inv_count 47 | temp_arr = [0]*n 48 | return _mergeSort(arr, temp_arr, 0, n-1) 49 | 50 | 51 | print(mergeSort(arr, n)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/11_stockbuysell.py: -------------------------------------------------------------------------------- 1 | # Stock Buy and Sell 2 | # https://practice.geeksforgeeks.org/problems/stock-buy-and-sell-1587115621/1 (Similar but total profit) 3 | # https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ 4 | 5 | # Time Complexity: O(n), Space Complexity: O(1) 6 | 7 | arr = [7,1,5,3,6,4] 8 | 9 | def maxProfit(prices): 10 | if len(prices)==0: 11 | return 0 12 | profit = 0 13 | cost = 0 14 | mn = prices[0] 15 | for i in range(len(prices)): 16 | mn = min(mn, prices[i]) 17 | cost = prices[i] - mn 18 | profit = max(profit, cost) 19 | return profit 20 | 21 | print(maxProfit(arr)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/12_rotatemat.py: -------------------------------------------------------------------------------- 1 | # Rotate Matrix 2 | # https://practice.geeksforgeeks.org/problems/rotate-by-90-degree-1587115621/1# (Similar but -90 degree rorated) 3 | # https://leetcode.com/problems/rotate-image/ 4 | 5 | # Time Complexity: O(n), Space Complexity: O(1) 6 | 7 | mat = [[1,2,3],[4,5,6],[7,8,9]] 8 | 9 | def rotate1(matrix): 10 | n = len(matrix) 11 | for i in range(n): 12 | for j in range(i): 13 | matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] 14 | 15 | for i in range(n): 16 | matrix[i].reverse() 17 | 18 | return matrix 19 | rotate1(mat) 20 | print(mat) 21 | 22 | def rotate2(matrix): 23 | n = len(matrix) 24 | for i in range(n//2): 25 | m = len(matrix[i]) - i - 1 26 | for j in range(i, m): 27 | tmp = matrix[m-j+i][i] 28 | matrix[m-j+i][i] = matrix[m][m-j+i] 29 | matrix[m][m-j+i] = matrix[j][m] 30 | matrix[j][m] = matrix[i][j] 31 | matrix[i][j] = tmp 32 | return matrix 33 | 34 | rotate2(mat) 35 | print(mat) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/13_ser2dmat.py: -------------------------------------------------------------------------------- 1 | # Search in a 2D matrix 2 | # https://practice.geeksforgeeks.org/problems/search-in-a-matrix17201720/1# 3 | # https://leetcode.com/problems/search-a-2d-matrix/ 4 | # https://leetcode.com/problems/search-a-2d-matrix-ii/submissions/ (Similar to GFG problem) 5 | 6 | arr = [[1,3,5,7],[10,11,16,20],[23,30,34,60]] 7 | n = len(arr) 8 | m = len(arr[0]) 9 | target = 3 10 | 11 | # Time Complexity: O(log(nm)), Space Complexity: O(1) 12 | def searchMatrix(matrix, target): 13 | n = len(matrix) 14 | m = len(matrix[0]) 15 | 16 | lo = 0 17 | high = n*m - 1 18 | 19 | while lo<=high: 20 | mid = (lo+high)//2 21 | if(matrix[mid//m][mid%m] == target): 22 | return True 23 | if(matrix[mid//m][mid%m] < target): 24 | lo = mid + 1 25 | else: 26 | high = mid - 1 27 | 28 | return False 29 | 30 | print(searchMatrix(arr, target)) 31 | 32 | 33 | # Time Complexity: O(n + m), Space Complexity: O(1) 34 | def matSearch(mat, N, M, X): 35 | res = 0 36 | 37 | i = 0 38 | j = M - 1 39 | 40 | while i=0: 41 | if(mat[i][j] == X): 42 | res = 1 43 | return res 44 | if(mat[i][j]0): 18 | if(nn%2 == 1): 19 | ans *= x 20 | nn -= 1 21 | else: 22 | x *= x 23 | nn /= 2 24 | if(n<0): 25 | ans = 1.0/ans 26 | return ans 27 | 28 | print(myPow(x, n)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/15_majelnb2.py: -------------------------------------------------------------------------------- 1 | # Majority Element (>N/2 times) 2 | # https://practice.geeksforgeeks.org/problems/majority-element-1587115620/1# 3 | # https://leetcode.com/problems/majority-element/ 4 | 5 | # Time Complexity: O(n), Space Complexity: O(1) 6 | 7 | arr = [3,2,3] 8 | 9 | def majorityElement(nums): 10 | c = 0 11 | el = -1 12 | for i in nums: 13 | if(c == 0): 14 | el = i 15 | if(el == i): 16 | c += 1 17 | else: 18 | c -= 1 19 | return el 20 | 21 | print(majorityElement(arr)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/16_majelnb3.py: -------------------------------------------------------------------------------- 1 | # Majority Element (>N/3 times) 2 | # https://www.geeksforgeeks.org/n3-repeated-number-array-o1-space/ 3 | # https://leetcode.com/problems/majority-element-ii/ 4 | 5 | # Time Complexity: O(n), Space Complexity: O(1) 6 | 7 | arr = [3,2,3] 8 | 9 | def majorityElement(nums): 10 | n = len(nums) 11 | c1 = 0 12 | c2 = 0 13 | el1 = -1 14 | el2 = -1 15 | for i in range(n): 16 | if(nums[i] == el1): 17 | c1 += 1 18 | elif(nums[i] == el2): 19 | c2 += 1 20 | elif(c1 == 0): 21 | c1 = 1 22 | el1 = nums[i] 23 | elif(c2 == 0): 24 | c2 = 1 25 | el2 = nums[i] 26 | else: 27 | c1 -= 1 28 | c2 -= 1 29 | out = [] 30 | ct1 = 0 31 | ct2 = 0 32 | for i in range(n): 33 | if(nums[i] == el1): 34 | ct1 += 1 35 | elif(nums[i] == el2): 36 | ct2 += 1 37 | if(ct1>(n/3)): 38 | out.append(el1) 39 | 40 | if(ct2>(n/3)): 41 | out.append(el2) 42 | 43 | return out 44 | 45 | print(majorityElement(arr)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/17_unipath.py: -------------------------------------------------------------------------------- 1 | # Grid Unique Paths 2 | # https://practice.geeksforgeeks.org/problems/count-all-possible-paths-from-top-left-to-bottom-right3011/1# 3 | # https://leetcode.com/problems/unique-paths/ 4 | 5 | # Time Complexity: O(m-1), Space Complexity: O(1) 6 | 7 | m = 3 8 | n = 7 9 | 10 | def uniquePaths(m, n): 11 | import math 12 | if not m or not n: 13 | return 0 14 | return int(math.factorial(m+n-2)/(math.factorial(n-1) * math.factorial(m-1))) 15 | 16 | print(uniquePaths(m, n)) 17 | 18 | def numberOfPaths( m, n): 19 | ans = 1 20 | for i in range(n, (m + n - 1)): 21 | ans *= i 22 | ans //= (i - n + 1) 23 | return int(ans%(10**9 + 7)) 24 | 25 | print(numberOfPaths(m, n)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/18_revpairs.py: -------------------------------------------------------------------------------- 1 | # Reverse Pairs (Leetcode) 2 | # https://leetcode.com/problems/reverse-pairs/ 3 | 4 | # Time Complexity: O(nlogn), Space Complexity: O(n) 5 | 6 | arr = [1,3,2,3,1] 7 | 8 | def reversePairs(nums): 9 | def merge(nums, low, mid, high): 10 | ct = 0 11 | j = mid+1 12 | for i in range(low, mid+1): 13 | while(j<=high and nums[i]>(2*nums[j])): 14 | j += 1 15 | 16 | ct += (j - (mid + 1)) 17 | 18 | tmp = [] 19 | left = low 20 | right = mid+1 21 | 22 | while(left<=mid and right<=high): 23 | if(nums[left]<=nums[right]): 24 | tmp.append(nums[left]) 25 | left += 1 26 | else: 27 | tmp.append(nums[right]) 28 | right += 1 29 | 30 | while(left<=mid): 31 | tmp.append(nums[left]) 32 | left += 1 33 | 34 | while(right<=high): 35 | tmp.append(nums[right]) 36 | right += 1 37 | 38 | for i in range(low, high+1): 39 | nums[i] = tmp[i-low] 40 | 41 | return ct 42 | 43 | 44 | 45 | def mergeSort(nums, low, high): 46 | if(low>=high): 47 | return 0 48 | mid = (low + high)//2 49 | c = 0 50 | c += mergeSort(nums, low, mid) 51 | c += mergeSort(nums, mid+1, high) 52 | c += merge(nums, low, mid, high) 53 | 54 | return c 55 | 56 | return mergeSort(nums, 0, len(nums)-1) 57 | 58 | print(reversePairs(arr)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/1_012sort.py: -------------------------------------------------------------------------------- 1 | # Sort an array of 0’s 1’s 2’s without using extra space or sorting algo 2 | # https://practice.geeksforgeeks.org/problems/sort-an-array-of-0s-1s-and-2s4231/1 3 | # https://leetcode.com/problems/sort-colors/ 4 | 5 | # Time Complexity: O(n), Space Complexity: O(1) 6 | 7 | arr = [2,0,2,1,1,0] 8 | 9 | lo = 0 10 | hi = len(arr) - 1 11 | mid = 0 12 | 13 | while mid<=hi: 14 | if(arr[mid] == 0): 15 | arr[lo], arr[mid] = arr[mid], arr[lo] 16 | lo += 1 17 | mid += 1 18 | elif(arr[mid] == 1): 19 | mid += 1 20 | elif(arr[mid] == 2): 21 | arr[mid], arr[hi] = arr[hi], arr[mid] 22 | hi -= 1 23 | 24 | print(arr) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/2_missrep.py: -------------------------------------------------------------------------------- 1 | # Repeat and Missing Number 2 | # https://practice.geeksforgeeks.org/problems/find-missing-and-repeating2512/1# 3 | 4 | 5 | # Time Complexity: O(n), Space Complexity: O(n) 6 | 7 | arr = [1, 3, 3] 8 | n = len(arr) 9 | 10 | uni = {} 11 | s = 0 12 | r = -1 13 | org_s = int((n*(n+1))/2) 14 | for i in arr: 15 | if i not in uni: 16 | uni[i] = 1 17 | else: 18 | uni[i] += 1 19 | r = i 20 | s += i 21 | 22 | print([r, (r - (s - org_s))]) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/3_mergerarr.py: -------------------------------------------------------------------------------- 1 | # Merge two sorted Arrays without extra space 2 | # https://practice.geeksforgeeks.org/problems/merge-two-sorted-arrays5135/1# 3 | # 4 | 5 | # Time Complexity: O(n+m*(log(n+m))), Space Complexity: O(1) 6 | # GAP Method, there is another approach in GFG editorial with TC O(n+m) and O(nm) 7 | 8 | arr1 = [1, 3, 5, 7] 9 | arr2 = [0, 2, 6, 8, 9] 10 | 11 | n = len(arr1) 12 | m= len(arr2) 13 | 14 | def n_gap(g): 15 | if(g<=1): 16 | return 0 17 | return (g//2) + (g%2) 18 | 19 | gap = n + m 20 | gap = n_gap(gap) 21 | 22 | while gap>0: 23 | i = 0 24 | while i + gaparr1[i + gap]): 26 | arr1[i], arr1[i + gap] = arr1[i + gap], arr1[i] 27 | i += 1 28 | 29 | j = gap-n if gap>n else 0 30 | while iarr2[j]): 32 | arr1[i], arr2[j] = arr2[j], arr1[i] 33 | i += 1 34 | j += 1 35 | 36 | if(jarr2[j + gap]): 40 | arr2[j], arr2[j + gap] = arr2[j + gap], arr2[j] 41 | j += 1 42 | 43 | gap = n_gap(gap) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/4_kadane.py: -------------------------------------------------------------------------------- 1 | # Kadane’s Algorithm 2 | # https://practice.geeksforgeeks.org/problems/kadanes-algorithm-1587115620/1# 3 | # https://leetcode.com/problems/maximum-subarray/ 4 | 5 | # Time Complexity: O(n), Space Complexity: O(1) 6 | 7 | arr = [1,2,3,-2,5] 8 | 9 | mx = -9999999 10 | tmp = 0 11 | for i in arr: 12 | tmp += i 13 | mx = max(mx, tmp) 14 | if(tmp<0): 15 | tmp = 0 16 | print(mx) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/5_mergint.py: -------------------------------------------------------------------------------- 1 | # Merge Overlapping Subintervals 2 | # https://leetcode.com/problems/merge-intervals/ 3 | 4 | # Time Complexity: O(nlogn), Space Complexity: O(n) 5 | 6 | arr = [[1,3],[2,6],[8,10],[15,18]] 7 | 8 | arr.sort() 9 | pair = arr[0] 10 | out = [] 11 | 12 | for i in arr: 13 | if(i[0]<=pair[1]): 14 | pair[1] = max(pair[1], i[1]) 15 | else: 16 | out.append(pair) 17 | pair = i 18 | 19 | out.append(pair) 20 | 21 | print(out) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/6_dupinarr.py: -------------------------------------------------------------------------------- 1 | # Find the duplicate in an array of N+1 integers. 2 | # https://leetcode.com/problems/find-the-duplicate-number/ 3 | 4 | # Time Complexity: O(n), Space Complexity: O(1) 5 | 6 | arr = [1,3,4,2,2] 7 | 8 | def findDuplicate1(nums): 9 | slow = nums[0] 10 | fast = nums[0] 11 | 12 | while True: 13 | slow = nums[slow] 14 | fast = nums[nums[fast]] 15 | if(slow == fast): 16 | break 17 | 18 | fast = nums[0] 19 | while slow != fast: 20 | slow = nums[slow] 21 | fast = nums[fast] 22 | 23 | return slow 24 | 25 | 26 | # Time Complexity: O(nlogn), Space Complexity: O(1) but here we are modifying the array 27 | 28 | def findDuplicate2(nums): 29 | nums.sort() 30 | for i in range(len(nums)-1): 31 | if(nums[i] == nums[i+1]): 32 | return(nums[i]) 33 | 34 | print(findDuplicate1(arr)) 35 | print(findDuplicate2(arr)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/7_matrixzero.py: -------------------------------------------------------------------------------- 1 | # Set Matrix Zeros 2 | # https://practice.geeksforgeeks.org/problems/boolean-matrix-problem-1587115620/1# (Similar but here we need to set 1's) 3 | # https://leetcode.com/problems/set-matrix-zeroes/ 4 | 5 | # Time Complexity: O(n*m), Space Complexity: O(1) 6 | 7 | arr = [[1,1,1],[1,0,1],[1,1,1]] 8 | 9 | def setZeroes(a): 10 | col = True 11 | n = len(a) 12 | m = len(a[0]) 13 | for i in range(n): 14 | if(a[i][0] == 0): 15 | col = False 16 | for j in range(1, m): 17 | if(a[i][j] == 0): 18 | a[0][j] = 0 19 | a[i][0] = 0 20 | 21 | for i in range(n-1, -1, -1): 22 | for j in range(m-1, 0, -1): 23 | if(a[i][0] == 0 or a[0][j] == 0): 24 | a[i][j] = 0 25 | if(col == False): 26 | a[i][0] = 0 27 | 28 | setZeroes(arr) 29 | 30 | print(arr) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/8_pascaltri.py: -------------------------------------------------------------------------------- 1 | # Pascal Triangle 2 | # https://practice.geeksforgeeks.org/problems/pascal-triangle0652/1# (Similar but return only row) 3 | # https://leetcode.com/problems/pascals-triangle-ii/ (Similar but return only row) 4 | # https://leetcode.com/problems/pascals-triangle/ 5 | 6 | # Time Complexity: O(n), Space Complexity: O(n) 7 | 8 | n = 4 9 | 10 | def getRow1(n): 11 | arr = [] 12 | j = 0 13 | k = n 14 | for i in range(n+1): 15 | if(i == 0 or i == n): 16 | arr.append(1) 17 | else: 18 | tmp = (arr[-1]*(k))//j 19 | arr.append(tmp) 20 | k -= 1 21 | j += 1 22 | return arr 23 | 24 | 25 | 26 | # Time Complexity: O(n^2), Space Complexity: O(n^2) 27 | 28 | def getRow2(n): 29 | arr = [] 30 | for i in range(n+1): 31 | tmp = [] 32 | for j in range(i+1): 33 | if(j == 0 or j == i): 34 | tmp.append(1) 35 | else: 36 | sm = arr[-1][j] + arr[-1][j-1] 37 | tmp.append(sm) 38 | arr.append(tmp) 39 | return arr[-1] 40 | 41 | print(getRow1(n)) 42 | print(getRow2(n)) -------------------------------------------------------------------------------- /Striver Sheet/Arrays/9_nextpermu.py: -------------------------------------------------------------------------------- 1 | # Next Permutation 2 | # https://practice.geeksforgeeks.org/problems/next-permutation5226/1 3 | # https://leetcode.com/problems/next-permutation/ 4 | 5 | # Time Complexity: O(n), Space Complexity: O(1) 6 | 7 | arr = [1,2,3] 8 | 9 | def nextPermutation(nums): 10 | i = len(nums) - 2 11 | while(i>=0 and nums[i+1]<=nums[i]): 12 | i-=1 13 | 14 | if(i>=0): 15 | j = len(nums) - 1 16 | while(j>=0 and nums[j]<=nums[i]): 17 | j-=1 18 | nums[i], nums[j] = nums[j], nums[i] 19 | def rev(nums1, start): 20 | i = start 21 | j = len(nums1)-1 22 | while(in_t): 25 | right -= 1 26 | else: 27 | #print(ans) 28 | ans.append([nums[i], nums[j], nums[left], nums[right]]) 29 | while(left=l): 18 | l = uni[s[r]] + 1 19 | uni[s[r]] = r 20 | r += 1 21 | mx = max(mx, r-l) 22 | return mx 23 | 24 | print(lswrc(st)) --------------------------------------------------------------------------------