LeetCode: Home robbery~~ Dynamic finishing

Posted by thipse_rahul on Thu, 17 Feb 2022 22:53:26 +0100

[1. House on the street, happy thief No. 1]

198. House raiding (medium)

You are a professional thief who plans to steal houses along the street. There is a certain amount of cash hidden in each room. The only restrictive factor affecting your theft is that the adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are intruded by thieves on the same night, the system will automatically alarm.

Given a non negative integer array representing the amount stored in each house, calculate the maximum amount you can steal overnight without touching the alarm device.

Example 1:

Input: [1,2,3,1]
Output: 4
Explanation: steal house 1 (amount = 1) and then steal house 3 (amount = 3).
Maximum amount stolen = 1 + 3 = 4.
Example 2:

Input: [2,7,9,3,1]
Output: 12
Explanation: steal house 1 (amount = 2), steal house 3 (amount = 9), and then steal house 5 (amount = 1).
Maximum amount stolen = 2 + 9 + 1 = 12.

Tips:

1 <= nums.length <= 100
0 <= nums[i] <= 400

/*
 * Every house has two choices, one is to steal, the other is not to steal
 * 1,If you steal house i, because you can't steal adjacent houses, the maximum amount of money that the scheme can steal is the maximum amount of stealing house i-2 + the money of house i
 * 2,If you don't steal house i, it means that the amount is the maximum amount of stealing house i-1
 * Therefore, the state transition equation can be obtained: DP [i] = math max(dp[i-1], dp[i-2] + nums[i])
 */
    public static int rob(int[] nums) {
    	int len = nums.length;
    	if( nums.length == 0 ) return 0;
    	else if( nums.length == 1 ) return nums[0];
    	else if( nums.length == 2 ) return Math.max(nums[0], nums[1]);
    	int[] dp = new int[len];  // Maximum amount that can be stolen when saving to house i
    	/* initialization */
    	dp[0] = nums[0];     // Only one room
    	dp[1] = Math.max(nums[0], nums[1]);  // Take the one with the largest amount among the two
    	
    	for( int i = 2; i < len; i++) {
    		dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i]);
    	}
    	return dp[len-1];
    }
Note: LeetCode There is another way to save space by scrolling arrays in the solution, which is attached here
    public static int rob(int[] nums) {
    	int len = nums.length;
    	if( nums.length == 0 ) return 0;
    	else if( nums.length == 1 ) return nums[0];
    	else if( nums.length == 2 ) return Math.max(nums[0], nums[1]);
    	/* initialization */
    	int first = nums[0];  
    	int second = Math.max(nums[0], nums[1]); 
    	
    	for( int i = 2; i < len; i++) {
    		int t = second;
    		second = Math.max(first + nums[i], second);
    		first = t;
    	}
    	return second;
    }

[2. The house under the ring, happy thief No. 2]

213. House raiding II (medium)

You are a professional thief. You plan to steal houses along the street. There is a certain amount of cash in each room. All the houses in this place are in a circle, which means that the first house and the last house are next to each other. At the same time, adjacent houses are equipped with interconnected anti-theft systems. If two adjacent houses are intruded by thieves on the same night, the system will automatically alarm.

Given a non negative integer array representing the amount stored in each house, calculate the maximum amount you can steal tonight without touching the alarm device.

Example 1:

Input: num = [2,3,2]
Output: 3
Explanation: you can't steal house 1 (amount = 2) and then house 3 (amount = 2) because they are adjacent.
Example 2:

Input: num = [1,2,3,1]
Output: 4
Explanation: you can steal house 1 (amount = 1) and then house 3 (amount = 3).
Maximum amount stolen = 1 + 3 = 4.
Example 3:

Input: num = [0]
Output: 0

Tips:

1 <= nums.length <= 100
0 <= nums[i] <= 1000

/*
 *  Put the state transition equation first: DP [i] = math max(dp[i-1], dp[i-2] + nums[i])
 *  Because the ring is formed, it is discussed in two cases:
 *  1,If you steal house 1, you cannot steal house nums length
 *  2,Stealing houses nums Length, you cannot steal house 1
 */
    public static int rob(int[] nums) {
    	int len = nums.length;
    	if( nums.length == 0 ) return 0;
    	else if( nums.length == 1 ) return nums[0];
    	else if( nums.length == 2 ) return Math.max(nums[0], nums[1]);
    	/*
    	 *  Because the ring is formed, it is discussed in two cases:
    	 *  1,If you steal house 1, you cannot steal house nums length
    	 *  2,Stealing houses nums Length, you cannot steal house 1
    	 */
    	return Math.max(Rob(nums, 0, nums.length - 1), Rob(nums, 1, nums.length));
    }
    
    public static int Rob(int[] nums, int start, int end) {
    	int first = nums[start];
    	int second = Math.max(nums[start], nums[start + 1]);
    	for( int i = start + 2; i < end; i++) {
    		int t = second;
    		second = Math.max(first + nums[i], second);
    		first = t;
    	}
    	return second;
    }

[3. I would like to call the thief the strongest house growing on a tree!]

337. House raiding III (medium)

After robbing a street and a circle of houses last time, the thief found a new area that could be stolen. This area has only one entrance, which we call "root". In addition to the "root", each house has and only has a "father" house connected to it. After some reconnaissance, the smart thief realized that "the arrangement of all houses in this place is similar to a binary tree". If two directly connected houses are robbed on the same night, the house will automatically call the police.

Calculate the maximum amount a thief can steal in a night without triggering the alarm.

Example 1:

Input: [3,2,3,null,3,null,1]

Output: 7
Explanation: the maximum amount a thief can steal in one night = 3 + 3 + 1 = 7
Example 2:

Input: [3,4,5,1,3,null,1]


Output: 9
Explanation: the maximum amount a thief can steal in one night = 4 + 5 = 9
Pass times 101306 submit times 164891

    	/*
    	 * [It is similar to the first two, but the road stolen this time has become two]
    	 * Now the thief's father (root) has two children (leaves), one called 'left' and the other called 'right'. The two children steal from left and right respectively
    	 * The maximum amount is the maximum amount stolen from the total amount of the thief's father and two children
    	 * But note: if the thief's father steals the money, both children can't steal it, otherwise they will be found; On the contrary, the thief's father can't steal
    	 * 
    	 * The general description is as follows:
    	 * Thief father does not steal: the maximum amount that can be stolen in the current node = 'left' child can steal the maximum amount + 'right' child can steal the maximum amount
    	 * The thief's father stole: the maximum amount that the current node can steal = 'left' the money that the child can get when he doesn't steal + 'right' the money that the child can get when he doesn't steal + the money of the current house
    	 * 
    	 * State transition equation: [0: amount when not stealing, 1: amount after stealing]
    	 * result[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
    	 * result[1] = left[0] + right[0] + root.val
    	 */
    public static int rob(TreeNode root) {
    	int[] result = Rob(root);
    	return Math.max(result[0], result[1]);
    }
    
    public static int[] Rob(TreeNode root) {
    	if( root == null ) return new int[] {0,0};
    	int[] result = new int[2];
    	
    	int[] left = Rob(root.left); 
    	int[] right = Rob(root.right);
    	
    	result[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
    	result[1] = left[0] + right[0] + root.val;
    	return result;
    }

[4. Could this be home robbing iv]

740. Delete and gain points (medium)

Give you an integer array nums, you can do some operations on it.

In each operation, select any num [i], delete it and obtain the number of num [i]. After that, you must delete each element equal to nums[i] - 1 or nums[i] + 1.

You have 0 points at the beginning. Returns the maximum number of points you can get through these operations.

Example 1:

Input: num = [3,4,2]
Output: 6
Explanation:
Delete 4 to get 4 points, so 3 is also deleted.
After that, delete 2 and get 2 points. Get a total of 6 points.
Example 2:

Input: num = [2,2,3,3,3,4]
Output: 9
Explanation:
Delete 3 to get 3 points, and then delete two 2 and 4.
After that, delete 3 again to obtain 3 points, and delete 3 again to obtain 3 points.
Get a total of 9 points.

Tips:

1 <= nums.length <= 2 * 104
1 <= nums[i] <= 104

	/*
	 * It may be a little strange how this thing has something to do with house raiding
	 * Note that when x is selected, neither x-1 nor x+1 can be selected. In order to get as many points as possible, x you should select all
	 * Therefore:
	 * We assume that the array given by the title is:
	 *     nums = [2,2,3,3,3,4]
	 *     
	 * Then after causing [house robbery]:
	 *     houses = [0,0,2,3,1]
	 *     
	 * Does it smell like that!
	 * Let's first paste the state transition equation of [home robbing]:
	 *     dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i])
	 * The state transition equation of this topic is given:
	 *     dp[i] = Math.max(dp[i - 1], dp[i - 2] + i * houses[i]);
	 *     Note: i * houses[i] represents the money of the house
	 * 
	 * After stealing houses on the streets, rings and trees, it seems that this is another perfect theft
	 */
    public static int deleteAndEarn(int[] nums) {
    	if( nums.length == 0 ) return 0;
    	else if( nums.length == 1) return nums[0];
    	int max = 0;
    	for( int i = 0; i < nums.length; i++) {  // Get the largest house number in order to construct [house robbery]
    		max = Math.max(max, nums[i]);
    	}
    	int[] houses = new int[max + 1];  
    	for( int i = 0; i < nums.length; i++) {
    		houses[nums[i]] ++;
    	}
    	return rob(houses, max);
    }
    
    public static int rob(int[] nums, int max) {
    	int len = nums.length;
    	int[] dp = new int[max + 1];
    	dp[0] = nums[0];
    	dp[1] = Math.max(nums[0], nums[1]);
    	for( int i = 2; i < len; i++) {
    		dp[i] = Math.max(dp[i-1], dp[i-2] + i * nums[i]);
    	}
    	return dp[max];
    }
Method of attaching a scrolling array
    public static int deleteAndEarn(int[] nums) {
    	if( nums.length == 0 ) return 0;
    	else if( nums.length == 1) return nums[0];
    	int max = 0;
    	for( int i = 0; i < nums.length; i++) {  // Get the largest house number in order to construct [house robbery]
    		max = Math.max(max, nums[i]);
    	}
    	int[] houses = new int[max + 1];  
    	for( int i = 0; i < nums.length; i++) {
    		houses[nums[i]] ++;
    	}
    	return rob(houses);
    }
    
    public static int rob(int[] nums) {
    	int len = nums.length;
    	int first = nums[0];
        int second = Math.max(nums[0], nums[1]);
    	for( int i = 2; i < len; i++) {
    		int t = second;
            second = Math.max(first + i * nums[i], second);
            first = t;
    	}
    	return second;
    }

[if the talented thief has a better place to steal, he will continue to update it]

Topics: Java leetcode Dynamic Programming