Combination Sum II - Leetcode 40 - Python

แชร์
ฝัง
  • เผยแพร่เมื่อ 27 ธ.ค. 2024

ความคิดเห็น • 59

  • @NeetCodeIO
    @NeetCodeIO  4 หลายเดือนก่อน +4

    NeetCode 150 - neetcode.io/practice
    Combination Sum Part 1 - th-cam.com/video/GBKI9VSKdGg/w-d-xo.html

  • @AnkitaNallana
    @AnkitaNallana 4 หลายเดือนก่อน +15

    Man, you single handedly upped my backtracking game! Your format is so easy to follow and I can actually solve more backtracking questions with this line of thought - you brought in a LOT of structure in how to think/reason a backtracking problem.
    I used to RUN AWAY when I'd see a backtracking problem, now I can get thru mediums and halfway thru hards but hey, I'll get there! Thank you so much!!

  • @akashverma5756
    @akashverma5756 4 หลายเดือนก่อน +17

    Backtracking has always been a headache for me.

  • @spiceybyte
    @spiceybyte 4 หลายเดือนก่อน +9

    The trick to this is similar to Subsets II. Solving and understanding Subsets II will make solving this problem easier

    • @romeosweeney8120
      @romeosweeney8120 2 หลายเดือนก่อน +3

      That's why they're in order on the roadmap 😉

  • @AsliArtist
    @AsliArtist 4 หลายเดือนก่อน +6

    The only solution on TH-cam that made sense (to me), because my code was exactly the same, I was only missing the while loop and ending up with a TLE. And now I know why. Thanks a ton, Nav!

    • @howto.3411
      @howto.3411 4 หลายเดือนก่อน

      same happened with me

  • @kooday
    @kooday 4 หลายเดือนก่อน

    Your explanations are even clearer now👌

  • @rajveersingh95
    @rajveersingh95 4 หลายเดือนก่อน +1

    I mostly pause your videos at the Drawing stage and go and solve it myself. That is what I am trying to learn from your channel : how to visualise the sequence of steps reqd for solving the problem

  • @michaelroditis1952
    @michaelroditis1952 4 หลายเดือนก่อน +1

    I'm surprised you don't need to make a copy of the "cur" because further down into the recursion I would expect that it would be problematic to change the list

  • @trevor6711
    @trevor6711 4 หลายเดือนก่อน

    We can significantly improve the time complexity by placing a conditional check before the while loop.
    Since we have sorted the array we know that if our current sum plus the current value we are viewing exceeds the target, then there is no need to search further right, since all values will exceed target by an even greater margin. We can check this and return if True.
    For example: candidates = [1,1,3,4,5,6,7,8,9], target = 3
    If we have [1,1] in our combination, then add 3 and see it that [1,1,3] exceeds 3 (ie. 5 > 3) then there is no need to also check that [1,1,4], [1,1,5], [1,1,6] etc are also in excess of the target
    Edit, just saw a different comment reflecting this, I'll leave this up in case it helps someone

  • @lizgarcia9807
    @lizgarcia9807 2 หลายเดือนก่อน

    Thanks for going over both runtime and space complexity in your recent videos :)

  • @Nameiscantsay
    @Nameiscantsay 2 หลายเดือนก่อน +1

    This problem is 99% similar to subsets 2 problem

  • @Zippo_1234
    @Zippo_1234 4 หลายเดือนก่อน

    This is so much easier to understand

  • @preetpatel292
    @preetpatel292 4 หลายเดือนก่อน +1

    For someone still struggling to understand why the loop is required, here is my take on this
    💡The core idea 💡
    If there are repeated elements you include elements from prefix (of group of same elements) and explore next but once you exclude the element you exclude all element of same values, because from here onwards you don't need to include any values, if it was required we would have already explored this case previously where choose the value from prefix.

  • @MP-ny3ep
    @MP-ny3ep 4 หลายเดือนก่อน

    Beautifully explained. Thank you

  • @yang5843
    @yang5843 4 หลายเดือนก่อน

    The solution was simpler than expected

  • @tannuiscoding
    @tannuiscoding 4 หลายเดือนก่อน

    This helped me a lot.

  • @chien-yuyeh9386
    @chien-yuyeh9386 4 หลายเดือนก่อน

    Nice!!🎉🎉

  • @chucksneedmoreland
    @chucksneedmoreland 4 หลายเดือนก่อน

    wondering if this could be done iteratively instead of using recursion?

  • @dzccccc
    @dzccccc 2 หลายเดือนก่อน

    alternatively, don't append the value and instead add an array with the next value, and you don't have to copy or pop either
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
    output = []
    candidates.sort()
    def backtrack(i=0, arr=[], total=0):
    if total == target:
    output.append(arr)
    return
    if i >= len(candidates) or total > target:
    return
    # add case
    backtrack(i + 1, arr + [candidates[i]], total + candidates[i])
    # don't add case
    while i + 1 < len(candidates) and candidates[i] == candidates[i + 1]:
    i += 1
    backtrack(i + 1, arr, total)
    backtrack()
    return output

  • @flwrnyz8926
    @flwrnyz8926 4 หลายเดือนก่อน +2

    The goat

  • @anirudhhosur3827
    @anirudhhosur3827 หลายเดือนก่อน

    DSA is sadly so hard. Difficult to break into MAANG companies.
    Create a strong portfolio in dev skills like full-stack, cloud, and now you're open for other roles.
    DSA is truly depressing.

  • @sugoonese4024
    @sugoonese4024 4 หลายเดือนก่อน

    If target was a large number (>100), will backtracking with array of length 100 give TLE (or stack overflow)

  • @mohamedabaza9700
    @mohamedabaza9700 2 หลายเดือนก่อน

    combination sumll=cobination subl + subsetll

  • @aayushtheapple
    @aayushtheapple 4 หลายเดือนก่อน +1

    I am still not getting the while loop part. Why it's needed ? Can anyone explain ?

    • @NeetCodeIO
      @NeetCodeIO  4 หลายเดือนก่อน +2

      Have you solved Combination Sum and 3Sum before?
      If not I would make sure you understand those first.
      Without the loop you will get duplicate combinations. I would highly recommend drawing the decision tree yourself, that's the only way to learn.
      Relying on explanations will only get you so far.

    • @nirmalgurjar8181
      @nirmalgurjar8181 4 หลายเดือนก่อน

      We need while loop to eliminate duplicate result. else it will give same result. ie. 1,1,1,3,4,5, target = 8, without while loop you will get 1,3,4 then again 1,3,4 and then again 1,3,4 but using while you ignore other 2 duplicate 1s and only process 1 once at given branch level so it would be just 1,3,4

  • @deepakjain4481
    @deepakjain4481 4 หลายเดือนก่อน

    applied the same but saying time limit exceded

  • @DNKF
    @DNKF 4 หลายเดือนก่อน

    Wondering if we can write Skip dfs first then the Including dfs? and how would it look?

    • @NeetCodeIO
      @NeetCodeIO  4 หลายเดือนก่อน +1

      you could but you would prob need another variable to keep track of the original index

    • @DNKF
      @DNKF 4 หลายเดือนก่อน

      @@NeetCodeIO thanks for the tip. Let me try it :)

    • @DNKF
      @DNKF 4 หลายเดือนก่อน

      @@NeetCodeIO
      It works! I missed the extra variable part at the first attempt.
      def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
      candidates.sort()
      res = []
      def helper(tmp, i, tar):
      if tar == 0:
      res.append(tmp.copy())
      return
      if i == len(candidates) or tar < 0:
      return
      j = i
      while i+1 < len(candidates) and candidates[i] == candidates[i+1]:
      i += 1
      helper(tmp, i+1, tar)
      tmp.append(candidates[i])
      helper(tmp, j+1, tar-candidates[j])
      tmp.pop()
      helper([], 0, target)
      return res

    • @DNKF
      @DNKF 4 หลายเดือนก่อน

      @@NeetCodeIO I have a general question. Could you share how did you "deep-understand" the leetcode skills? Like how we can study and check if we are ready and learned LC deep enough.
      Personally, I have a problem that I could understand a LC problem after watching your videos and understanding the logic. However, when I tried to do the other problems in same category, I feel like I am not truly understanding them and not learned deep enough.

  • @fabricio5p
    @fabricio5p 4 หลายเดือนก่อน

    tough one

  • @FizzaAhmad-up8ns
    @FizzaAhmad-up8ns 4 หลายเดือนก่อน

    Upload today's(14 august) daily problem please!

  • @vishaalkumaranandan2894
    @vishaalkumaranandan2894 4 หลายเดือนก่อน

    You have already posted this video already in your other channel

  • @UrsKarthikHere
    @UrsKarthikHere 4 หลายเดือนก่อน

    @NeetCodeIO or anyone please help
    how total is decreasing after pop?

    • @NeetCodeIO
      @NeetCodeIO  4 หลายเดือนก่อน

      We never modify total, we pass in the sum as the argument in the skip case. I feel like it's pretty straight forward if you read the code

    • @UrsKarthikHere
      @UrsKarthikHere 4 หลายเดือนก่อน

      Actually Confused between cur and total, both are passing as arguments,cur changing and total remains same, after some visualisation, finally what i understand is cur is poining in memory but not total.
      Thanks@@NeetCodeIO , got it.

  • @tuanhungphamcong1340
    @tuanhungphamcong1340 4 หลายเดือนก่อน

    can someone explain for me deeper why i cant use dynamic programing ?

    • @NeetCodeIO
      @NeetCodeIO  4 หลายเดือนก่อน

      You can but it won't improve the time complexity because you still have to generate the solution set which would be n*2^n in worst case

    • @MAK_007
      @MAK_007 3 หลายเดือนก่อน

      because there is nothing repeating. every operation is unique

  • @Manikandan-li4cd
    @Manikandan-li4cd 4 หลายเดือนก่อน +1

    we can skip the while loop, if the total is greater then the target, its unnecessary to go to recursion in this case

    • @NeetCodeIO
      @NeetCodeIO  4 หลายเดือนก่อน +3

      What's the solution without the loop?

    • @Manikandan-li4cd
      @Manikandan-li4cd 4 หลายเดือนก่อน

      @@NeetCodeIO what i meant is if the total is greater than the target we can skip the while loop so the recursion wont happen something like below
      if (total + candidates[index]) < target:
      // do while loop and recursion stuff

    • @serhiikopytchuk
      @serhiikopytchuk 4 หลายเดือนก่อน

      @@Manikandan-li4cd We just do same thing into the dfs function. So there no need to repeat

    • @Manikandan-li4cd
      @Manikandan-li4cd 4 หลายเดือนก่อน

      @@serhiikopytchuk yeah i agree! But what i meant is from the above eg if we know that 1,1,2,5 is greater than the target! We dont need to again dfs for 1,1,2,7 or 1,1,2,8 or 1,1,2,10 etc

    • @nirmalgurjar8181
      @nirmalgurjar8181 4 หลายเดือนก่อน +2

      DRY: don't repeat yourself principle, we are checking at top if sum is greater we are returning, why to write same thing again below while loop.

  • @sami9323
    @sami9323 3 หลายเดือนก่อน

    You glossed over the most important part - with the way you explained it, [1,1,6] should never be possible because you're only ever recurring over unique elements. Why is the second 1 in [1,1,6] included?
    For an example where you have [1,1,....,6,6...] and target=8, why won't you end up with [1,1,6] twice?

    • @sami9323
      @sami9323 3 หลายเดือนก่อน

      Oh oops you did mention it - it's because our two branches are:
      A) exclude ALL occurrences of the element from this point onwards(while loop till we find a next unique element in the sorted array), this happens even IF the element is in our path
      B) include the element, even if it's in our path

  • @ashishagarwal706
    @ashishagarwal706 4 หลายเดือนก่อน

    class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
    curset = []
    subset = []
    candidates.sort()
    def helper(i,nums,curset,subset):
    if i >= len(nums):
    return

    if sum(curset) > target:
    return

    if sum(curset) == target:
    subset.append(curset.copy())
    return

    curset.append(nums[i])
    helper(i+1,nums,curset,subset)
    curset.pop()
    while i+1 < len(nums) and nums[i] == nums[i+1]:
    i = i + 1
    helper(i+1,nums,curset,subset)
    return subset

    return helper(0,candidates,curset,subset)

    This code is very similar, but only gives me solution [[1,2,2]] for the use case candidates = [2,5,2,1,2], target = 5. Can someone please explain ?

    • @rajaththomaskurian8046
      @rajaththomaskurian8046 4 หลายเดือนก่อน

      You must first check if the current sum is equal to target before checking if i >= len(candidates) since i will be greater than length for the last element case (here when when you add 5 to curset, i will be 6)

  • @sherazdotnet
    @sherazdotnet 3 หลายเดือนก่อน

    I believe there is a mistake here. You pointed out that we can't the first approach where we take each number and then combine with others because it will cause duplicate. That's incorrect because question is pointing out that numbers are unique. This means that when you move to next index, you won't see the same number again. Therefore, you can take that approach. Start from an index and go all the way forward and backtrack.
    for(var i=index; i < input.Length; i++) {
    var value = input[i];
    list.Add(value);
    FindTarget(index, target-value, list, input);
    list.RemoveAt(list.Count-1);

    FindTarget(index+1, target, list, input);
    }
    This should work fine.

    • @NeetCodeIO
      @NeetCodeIO  3 หลายเดือนก่อน

      Actually the question does not say numbers are unique, thats combination sum i

  • @calvin_713
    @calvin_713 2 หลายเดือนก่อน

    Such a confusing problem..

  • @Flekks
    @Flekks 4 หลายเดือนก่อน

    I can not solve backtracking problems on my own. Using recursion is hard for me.