House Robber II - Dynamic Programming - Leetcode 213

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

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

  • @NeetCode
    @NeetCode  3 ปีที่แล้ว +4

    Dynamic Programming Playlist: th-cam.com/video/73r3KWiEvyk/w-d-xo.html

  • @vinoddiwan5792
    @vinoddiwan5792 3 ปีที่แล้ว +58

    I have no words, how can I thank you. your explanation is great.
    Being from an Electronics background it is very tough for me to learn code.
    you made it simple

  • @appcolab
    @appcolab 2 ปีที่แล้ว +9

    Very helpful, thank you !!
    Instead of passing 3 args in max, we can also check if the list has 3 or less elements. Above 86% faster
    def rob(self, nums: List[int]) -> int:
    # Check if nums has elements
    if len(nums)

  • @joshr9809
    @joshr9809 ปีที่แล้ว +9

    I would just add by means of explaining why we leave one out - when we remove an element, the "circle" of houses becomes a line of houses, reducing the house robber 2 problem to the house robber 1 problem.

  • @jnjc738
    @jnjc738 2 ปีที่แล้ว +4

    Dude, you keep blowing my mind! Everytime I am stucked I will come over to your video to get some EMOTIONAL DAMAGE

  • @adipratapsinghaps
    @adipratapsinghaps 2 ปีที่แล้ว +13

    Doesn't num[1:] and num[:-1] create 2 new arrays? Isn't this technically O(N) space complexity? Asking coz I am not much hands on with python.

    • @CJ-ff1xq
      @CJ-ff1xq 2 ปีที่แล้ว +6

      Yes it does. You can modify the original array instead and pass it to helper

  • @ChiCity511
    @ChiCity511 ปีที่แล้ว +4

    I figured out house robber 1 on my own but couldn't figure this one out without looking at the solution. I feel dumb lol

  • @nguyen-dev
    @nguyen-dev 2 ปีที่แล้ว +4

    Some optimizations to the original solution:
    * passing indexes instead of creating new arrays when passing to helper function.
    * in the first iteration, keeptrack a boolean to determine if we decide to rob the first house or not.
    Before start the second iteration, check the result if we decide to rob the last house. If the result doesn't need to rob the first house, we can skip the 2nd call to helper function.

    • @_control_
      @_control_ 2 ปีที่แล้ว

      Can you explain on the second optimization?

    • @nguyen-dev
      @nguyen-dev ปีที่แล้ว

      Not sure what happens to TH-cam, my replies are always disappear.
      Try the last time to post the solution with optimization. The tradeoff is that it's a lot more complex than the original solution.
      fun rob(nums: IntArray): Int {
      // TO(n) / SO(1)

      // return: max, includeFirstHouse, includeLastHouse
      fun innerRob(from: Int, to: Int): Triple {
      // Pair
      var maxA = 0 to false
      var maxB = 0 to false
      var includeLastHouse = false

      for (i in from .. to) {
      val num = nums[i]

      if (maxA.first + num > maxB.first) {
      // steal current house
      maxB = ((maxA.first + num) to (i == 0 || maxA.second)).also { maxA = maxB }
      includeLastHouse = i == to
      } else if (maxA.first + num == maxB.first) {
      maxB = maxB.first to (maxA.second && maxB.second).also { maxA = maxB }
      includeLastHouse = i == to
      } else {
      // don't steal current house
      maxA = maxB
      }
      }

      return Triple(maxB.first, maxB.second, includeLastHouse)
      }

      val ans1 = innerRob(0, nums.lastIndex - 1)

      return if (ans1.second || ans1.third) {
      // if we rob the first or the previous of the last house
      // we need to check if we should rob the last house
      val ans2 = innerRob(1, nums.lastIndex)
      max(ans1.first, ans2.first)
      } else {
      // if we didn't rob the first and the previous of the last house
      // we can definitely rob the last house
      ans1.first + nums.last()
      }
      }

    • @nguyenquoctran8423
      @nguyenquoctran8423 ปีที่แล้ว

      Python list slicing does not create new arrays so it's the same as passing indexes.

    • @hoixthegreat8359
      @hoixthegreat8359 ปีที่แล้ว

      @@nguyenquoctran8423it creates a shallow copy, which is O(N)

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

    I laughed so hard after breaking my head for 30 min even after solving houserob1 lol

  • @balajinagappan1311
    @balajinagappan1311 2 ปีที่แล้ว +2

    Thanks for making out these vidoes .They are crisp and explanative at the same time !! They are of great help. You definitely deserve more subscribers

  • @uuid9595
    @uuid9595 3 ปีที่แล้ว +7

    Nice work! Thanks for sharing these solutions. I think you could further improve this solution by setting the first element to '0', then running the helper on the array, add it back, and do the same for the last element. This will save Python having to do two O(n) operations to 'remove' that first element and the last element.

    • @director8656
      @director8656 3 ปีที่แล้ว

      read my thoughts, i wonder how much it actually impacts the solution...

    • @nemesis_rc
      @nemesis_rc 3 ปีที่แล้ว +3

      @@director8656 not much, because its already O(n) which is almost equal to O(k*n)

    • @director8656
      @director8656 3 ปีที่แล้ว +2

      @@nemesis_rc Yeah, I thought so don't think it could make or break a solution..

    • @dk20can86
      @dk20can86 2 ปีที่แล้ว

      Or just store the original array in an instance variable and then work with indexes instead of copying over the entire array for each method call

    • @piclkesthedrummer6439
      @piclkesthedrummer6439 ปีที่แล้ว

      it will probably make it worse because nums[1:] deletes nothing just goes to said indexes, which means it will make n-1 calls to an array, but if you set 1 to zero and go through it it will do 1 changing operation and n calls to array which is not faster

  • @junkcast7450
    @junkcast7450 2 ปีที่แล้ว +3

    Thanks for the explanation

  • @vinayak186f3
    @vinayak186f3 2 ปีที่แล้ว +20

    Don't know why I'm do dumb

  • @leoncai7714
    @leoncai7714 2 ปีที่แล้ว +1

    very clear!! I used Java Deque to store recent values

  • @sivaganesh4489
    @sivaganesh4489 2 ปีที่แล้ว +2

    subscribed by watching half of the video

  • @alirezafereydoni2827
    @alirezafereydoni2827 2 ปีที่แล้ว +1

    Thanks for your awesome explanation for both house rob 1 and 2

  • @varunshrivastava2706
    @varunshrivastava2706 2 ปีที่แล้ว +3

    After understanding the solution I am feeling dizzy, don't know why am I soooo dumb!!!!!

    • @slnop9724
      @slnop9724 2 ปีที่แล้ว +3

      I also felt the same way!!!! I banged my head for two hours LOL🤣

    • @varunshrivastava2706
      @varunshrivastava2706 2 ปีที่แล้ว

      @@slnop9724 😂😂

  • @_control_
    @_control_ 2 ปีที่แล้ว +2

    Here is my solution without the helper function, in this way, we don't allocate two new arrays.
    class Solution:
    def rob(self, nums: List[int]) -> int:
    # Check if only one element
    if len(nums) == 1:
    return nums[0]

    # First iteration
    rob1, rob2 = 0, 0
    for i in nums[:-1]:
    temp = max(i+rob1, rob2)
    rob1 = rob2
    rob2 = temp
    res1 = rob2
    # Second iteration
    rob1, rob2 = 0, 0
    for i in nums[1:]:
    temp = max(i+rob1, rob2)
    rob1 = rob2
    rob2 = temp
    res2 = rob2
    return max(res1,res2)

  • @sahilchoudhary1473
    @sahilchoudhary1473 ปีที่แล้ว +1

    you are the best teacher for data structure and algorithms , all over the youtube

  • @check_mate
    @check_mate 2 ปีที่แล้ว +1

    i was able to do house robber 1 by myself, had trouble with house robber 2 now i just feel dumb after watching this explanation

  • @umamahesh546
    @umamahesh546 ปีที่แล้ว

    U just nailed it man🔥

  • @wellzhang5234
    @wellzhang5234 10 วันที่ผ่านมา

    Can you also prove max(nums) = max(dp(nums[1:]), dp[nums[:-1]]), leaving out the edge case?

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

    Thanks

  • @ehabteima
    @ehabteima ปีที่แล้ว

    Great solution but the space complexity would be O(n) I expect since you're passing two new arrays to the function. The new arrays will be referencing the original array but they still need space n nonetheless. It would be O(1) if you pass the index instead.

    • @PrateekGole
      @PrateekGole ปีที่แล้ว

      slicing doesn't create new lists

  • @HiVikas
    @HiVikas ปีที่แล้ว

    i could solve the house robber one but I was not able to see this small observations to solve the second one. (EMOTIONAL DAMAGE !!!!)

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

    This is just amazing!!!

  • @AmolGautam
    @AmolGautam 2 ปีที่แล้ว

    Thank you for the explaination.

  • @user-cf5uf9sw1u
    @user-cf5uf9sw1u 2 ปีที่แล้ว

    Awesome, great as always!

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

    Thanks :)

  • @datle2863
    @datle2863 2 ปีที่แล้ว

    Gosh it is so easy to go from HR1 to HR2

  • @atharvakalele37
    @atharvakalele37 2 ปีที่แล้ว +3

    public static int f(int n, int[] nums){
    if(n==0){
    return 0;
    }
    if(n

    • @ivymboya
      @ivymboya 2 ปีที่แล้ว +1

      Yes you can.
      class Solution:
      def rob(self, nums: List[int]) -> int:
      return max(nums[0], self.rob1(nums[:-1]), self.rob1(nums[1:]))

      def rob1(self, nums):
      if len(nums) == 0:
      return 0
      if len(nums) == 1:
      return nums[0]
      if len(nums) == 2:
      return max(nums[0], nums[1])
      dp = nums[:]
      dp[0] = nums[0]
      dp[1] = max(nums[0], nums[1])
      for i in range(2, len(nums)):
      dp[i] = max(dp[i-1], dp[i-2]+ dp[i])
      return dp[len(nums)-1]

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

    Good one

  • @kentsang9376
    @kentsang9376 3 ปีที่แล้ว

    Great explanation

  • @leoncai7714
    @leoncai7714 2 ปีที่แล้ว

    very clear!!

  • @jonaskhanwald566
    @jonaskhanwald566 3 ปีที่แล้ว +3

    Bro pls upload longest common subsequence (LCS) WITH ONE DIMENSIONAL DP SOLUTION
    eagerly waiting
    U r the best

  • @anjanobalesh8046
    @anjanobalesh8046 ปีที่แล้ว

    Instead of calling the helper function twice
    We can call it once passing all the array elements except first and last index
    Then return Max (arr[0]+helper function output ,arr[last]+helper function output)
    This allows not to loop over 2 times

    • @MoonPatel
      @MoonPatel ปีที่แล้ว +2

      I guess that wont wokr beacause we may take adjacent houses without knowing in this way

    • @wellzhang5234
      @wellzhang5234 10 วันที่ผ่านมา

      yea it won't work in that way

  • @dr.merlot1532
    @dr.merlot1532 2 ปีที่แล้ว +1

    house rubber.

  • @gazizayestemirova3899
    @gazizayestemirova3899 3 ปีที่แล้ว

    Really great explanation! Thank you 🙌🏻

  • @sharath5796
    @sharath5796 2 ปีที่แล้ว +1

    Python solution using DP:
    class Solution:
    def rob(self, nums: List[int]) -> int:
    if len(nums) == 1:
    return nums[0]
    def rob1(nums):
    dp = [0]*(len(nums)+1)
    dp[0] = 0
    dp[1] = nums[0]
    for i in range(1,len(nums)):
    dp[i+1] = max(dp[i],dp[i-1]+nums[i])
    return dp[len(nums)]
    a = rob1(nums[1:])
    b = rob1(nums[:-1])
    return max(a,b)

  • @deshawnbattle7510
    @deshawnbattle7510 2 ปีที่แล้ว

    Goddam Genius

  • @frogloki882
    @frogloki882 ปีที่แล้ว

    I'm so stupid!.such a simple idea,wasted 30min on trying and got nowhere.😭😭

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

    D9ne and dusted

  • @jasonliu9790
    @jasonliu9790 3 ปีที่แล้ว +1

    yesssssssssssssssssssssssssssssssssssss

  • @nischayrawat682
    @nischayrawat682 2 ปีที่แล้ว +1

    dont waste so much time on explaining previous problem

  • @anilchaudhry804
    @anilchaudhry804 2 ปีที่แล้ว

    how do i connect with you on linkedin