diff --git a/0-1Knapsack.swift b/0-1Knapsack.swift new file mode 100644 index 00000000..08a1abf6 --- /dev/null +++ b/0-1Knapsack.swift @@ -0,0 +1,90 @@ +// +// 0-1Knapsack.swift +// DSA-Practice +// +// Created by Paridhi Malviya on 1/20/26. +// + +/* + greedy wouldn't work. + so, have exhaustive approach. come up with all the possibilities of choose and not choose + weight array - [10, 20, 30]. Weightts can be chosend only once + profit array = [60, 100, 120] + weight allowed = 50 + achieve maximum profit while putting elements within the capacity. + greedy -> first choose 30 to get max profit 120, then choose 20 to have 100 more. profit - 220 greedy works for capacity 50. + If capacity is changed to 30 -> I choose 30, profit attained - 120. Now can't choose any other. + But if I decide to choose 10 and 20 -> total profit - 160. + So, greedy doesn;t work. Chooseing the maximum profit element wouldn't always give us the maximum profit. + + If greedy doesn;t work, we have to be exhaustive. + Have all the possibilities of choose and not choose. + + eg [10, 20, 30, 40] + At every node, we have 2 options - choose and don't choose. + If we choose an element, then add it's weight and we will be left with rest of the elements. + time complexity - 2^(m + n) -> m -> no of elements in the weight array, n -> capacity + space complexity - (m + n) recursive stack space + + We will be encountering repeated subproblems. So, can use DP. We have two input parameters - weights array and the capacity. So, use 2D matrix + In matrix, at each place, choose maximum between choose and no choose scenario. + time complexity - O(m * n) + space complexity - O(m * n) + + + */ +class ZeroOneKnapsack { + + var profit = [60, 100, 120] + var weight = [10, 20, 30] + let capacity = 50 + + init() { + let totalProfit = helper(profit: [60, 100, 120], weight: [10, 20, 30], capacity: 50, i: 0, totalProfit: 0) + print("ZeroOneKnapsack totalProfit \(totalProfit)") + + let profit = findMaximumProfitUsingDP() + print("profit using DP \(profit)") + } + + //i - index on weight + func helper(profit: [Int], weight: [Int], capacity: Int, i: Int, totalProfit: Int) -> Int { + //base case + if (i >= weight.count) { + return totalProfit + } + + //logic + //no choose + let case0 = helper(profit: profit, weight: weight, capacity: capacity, i: i + 1, totalProfit: totalProfit) + + //choose case + var case1 = 0 + //only if the current weight is smaller than the capacity + if (weight[i] <= capacity) { + case1 = helper(profit: profit, weight: weight, capacity: capacity - weight[i], i: i + 1, totalProfit: totalProfit + profit[i]) + } + + return max(case0, case1) + + } + + func findMaximumProfitUsingDP() -> Int { + + let m = weight.count + let n = capacity + var dp = Array(repeating: Array(repeating: 0, count: n + 1), count: m + 1) + + for i in 1...m { + for j in 1...n { + if (j < weight[i-1]) { + dp[i][j] = dp[i-1][j] + } else { + dp[i][j] = max(dp[i-1][j], profit[i-1] + dp[i-1][j-weight[i-1]]) + } + } + } + + return dp[m][n] + } +} diff --git a/Problem1.cpp b/Problem1.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/Problem1.java b/Problem1.java deleted file mode 100644 index e69de29b..00000000 diff --git a/Problem2.cpp b/Problem2.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/Problem2.java b/Problem2.java deleted file mode 100644 index e69de29b..00000000 diff --git a/README.md b/README.md deleted file mode 100644 index c87cd58c..00000000 --- a/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Competitive-Coding-2 - -Please submit the interview problems posted in slack channel here. The problems and statements are intentionally not shown here so that students are not able to see them in advance diff --git a/TwoSum.swift b/TwoSum.swift new file mode 100644 index 00000000..73b7bf23 --- /dev/null +++ b/TwoSum.swift @@ -0,0 +1,72 @@ +// +// TwoSum.swift +// DSA-Practice +// +// Created by Paridhi Malviya on 1/6/26. +// + +/* + want unique pairs + can think elemets as pairs. Used for + two pointers + + -> naive approach- O(n2) -> nested iterations + approach 2 - use hash map. Search for compliment in + + -> O(n) time complexity. Space - O(n) + use hash set. and only store numbers or compliment. store number and look for compliment. or vice versa + +-> binary search - sort the array. Do binary search for compliment. + + ->If array is already sorted. time complexity - O(n logn) + for each element we are doingnbinary serahc. So log n for all elements of an array. -> n logn + to sort the array - O(n log n) + time complexity - O(n logn n) + O(n log n) = O(n log n) (avoid constant) + + -> Two pointer - keep on increasing the pointer 1 and decreasing the pointer 2 + n log n for sortuing. O(n) for two pointers + + => If I have repeats in the numbers array but we don't want repeats in pair. + [-3, 0, -2, -2, -1, -1, 0, 0, 0 7, 7, 6, 1, 1, 9, 9 ,9, -1, 0] + 1. can use hash set to avoid duplicated of a pair. O(n) space complexity. + + 2. Sort the array and use two pointers solution. + [-4, -3, -2, -2, -1, -1, -1, 0, 0 , 0, 1, 1, 1, 2, 2 ] + O (n logn n), no extra space + right pointer value + left pointer value > target, decrease right pointer. + ----- < target, increase left pointer to have bigger value to make bigger sum + If we are at the target -> move both the pointers and record the pair. + Move the left and right pointers until we hit the next unique element. In this way, we avoided hash set for storage + + Nested iterations can be optimizied using + binary search, hashing, two pointers, + + + -> 3 sum -> 1 fixed pointer and two sum + -> 4 sum - > take 2 pivots. and 2 pointers + + */ + +class TwoSum { + + init() { + let resultIndex = twoSum(nums: [2,7,11,15], target: 13) + print("resultIndex \(resultIndex)") + } + + func twoSum(nums: [Int], target: Int) -> (Int, Int){ + var map: Dictionary = [:] + for i in 0..