Kadane 算法 53,918,2272,1186

53. Maximum Subarray
Easy

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

A subarray is a contiguous part of an array.

 Example 1:

Input: nums = [-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Example 2:

Input: nums = [1]
Output: 1

Example 3:

Input: nums = [5,4,-1,7,8]
Output: 23 

Constraints:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

Follow up: If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

解法:dp,我们只需要关心截止前一个元素的最大值,如果截止前一个元素最大值大于0 那我们就加它,否则的话不加

class Solution {
    public int maxSubArray(int[] nums) {
        int[] result = new int[nums.length];
        result[0]=nums[0];
        int max = result[0];
        for(int i=1;i<nums.length;i++){
            result[i] = nums[i] + ( result[i-1] >= 0 ? result[i-1] : 0 );
            max = Math.max(max,result[i]);
        }
        return max;
    }
}

空间优化:

class Solution {
    public int maxSubArray(int[] nums) {
        int max = nums[0];
        int sum = nums[0];
        for(int i=1;i<nums.length;i++){
            sum = nums[i] + ( sum >= 0 ? sum : 0 );
            max = Math.max(max,sum);
        }
        return max;
    }
}

 

918. Maximum Sum Circular Subarray
Medium

Given a circular integer array nums of length n, return the maximum possible sum of a non-empty subarray of nums.

A circular array means the end of the array connects to the beginning of the array. Formally, the next element of nums[i] is nums[(i + 1) % n] and the previous element of nums[i] is nums[(i - 1 + n) % n].

A subarray may only include each element of the fixed buffer nums at most once. Formally, for a subarray nums[i], nums[i + 1], ..., nums[j], there does not exist i <= k1k2 <= j with k1 % n == k2 % n.

Example 1:

Input: nums = [1,-2,3,-2]
Output: 3
Explanation: Subarray [3] has maximum sum 3.

Example 2:

Input: nums = [5,-3,5]
Output: 10
Explanation: Subarray [5,5] has maximum sum 5 + 5 = 10.

Example 3:

Input: nums = [-3,-2,-3]
Output: -2
Explanation: Subarray [-2] has maximum sum -2.

 Constraints:

  • n == nums.length
  • 1 <= n <= 3 * 104
  • -3 * 104 <= nums[i] <= 3 * 104

class Solution {
    public int maxSubarraySumCircular(int[] nums) {
        int max = Integer.MIN_VALUE;
        int allSum = 0;
        int sum = 0;
        //求连续子数组最大和
        for(int i=0;i < nums.length; i++){
            sum = sum>0 ? sum+nums[i] : nums[i];
            max = Math.max(sum, max);
            allSum += nums[i];
        }
        //求连续子数组最小和
        int min = Integer.MAX_VALUE;
        sum = 0;
        for(int i=0;i < nums.length; i++){
            sum = sum<0 ? sum+nums[i] : nums[i];
            min = Math.min(sum, min);
        }
        //如果最小和等于加总的和,说明都是负数,直接返回负数中的最大值
        return allSum == min ? max : Math.max(max, allSum-min);
    }
}

 

2272. Substring With Largest Variance
Hard

The variance of a string is defined as the largest difference between the number of occurrences of any 2 characters present in the string. Note the two characters may or may not be the same.

Given a string s consisting of lowercase English letters only, return the largest variance possible among all substrings of s.

A substring is a contiguous sequence of characters within a string.

 Example 1:

Input: s = "aababbb"
Output: 3
Explanation:
All possible variances along with their respective substrings are listed below:
- Variance 0 for substrings "a", "aa", "ab", "abab", "aababb", "ba", "b", "bb", and "bbb".
- Variance 1 for substrings "aab", "aba", "abb", "aabab", "ababb", "aababbb", and "bab".
- Variance 2 for substrings "aaba", "ababbb", "abbb", and "babb".
- Variance 3 for substring "babbb".
Since the largest possible variance is 3, we return it.

Example 2:

Input: s = "abcde"
Output: 0
Explanation:
No letter occurs more than once in s, so the variance of every substring is 0.

 Constraints:

  • 1 <= s.length <= 104
  • s consists of lowercase English letters.
class Solution {
    public int largestVariance(String s) {
        int[] count = new int[26];
        int max = 0;
        for(int i=0;i<s.length();i++) count[s.charAt(i)-'a']++;
        for(int i = 0;i < 26;i++){
            for(int j = 0;j < 26;j++){
                if(count[i]==0 || count[j]==0 || i==j) continue;
                List<Integer> list = new ArrayList();
                for(int k=0;k<s.length();k++){
                    if(s.charAt(k) - 'a' == i) list.add(1);
                    else if(s.charAt(k) - 'a' == j) list.add(-1);
                }
                max = Math.max(max, getKadane(list));
            }
        }
        return max;
    }
    private int getKadane(List<Integer> list){
        int[] dp1 = new int[list.size()];
        int[] dp2 = new int[list.size()];
        dp1[0] = list.get(0);
        for(int i=1;i<list.size();i++) 
            dp1[i] = Math.max(list.get(i), dp1[i-1]+list.get(i));
        dp2[list.size()-1] = list.get(list.size()-1);
        for(int i=list.size()-2;i>=0;i--) 
            dp2[i] = Math.max(list.get(i), dp2[i+1]+list.get(i));
        
        int max = 0;
        for(int i=0;i<dp1.length;i++){
            if(list.get(i)==-1)      
                max = Math.max(dp1[i]+dp2[i]+1, max);
        }
        return max;
    }
}

 时间复杂度: O(26*26*N)

1186. Maximum Subarray Sum with One Deletion
Medium

Given an array of integers, return the maximum sum for a non-empty subarray (contiguous elements) with at most one element deletion. In other words, you want to choose a subarray and optionally delete one element from it so that there is still at least one element left and the sum of the remaining elements is maximum possible.

Note that the subarray needs to be non-empty after deleting one element.

 Example 1:

Input: arr = [1,-2,0,3]
Output: 4
Explanation: Because we can choose [1, -2, 0, 3] and drop -2, thus the subarray [1, 0, 3] becomes the maximum value.

Example 2:

Input: arr = [1,-2,-2,3]
Output: 3
Explanation: We just choose [3] and it's the maximum sum.

Example 3:

Input: arr = [-1,-1,-1,-1]
Output: -1
Explanation: The final subarray needs to be non-empty. You can't choose [-1] and delete -1 from it, then get an empty subarray to make the sum equals to 0. 

Constraints:

  • 1 <= arr.length <= 105
  • -104 <= arr[i] <= 104
class Solution {
    public int maximumSum0(int[] arr) {
        int[] noInclude = new int[arr.length];
        int[] include = new int[arr.length];
        noInclude[0] = 0;
        include[0] = arr[0];
        int result = Integer.MIN_VALUE;
        int sum = arr[0];
        for(int i = 1; i < arr.length; i++) {
            sum += arr[i];
            //如果不delete,那么前面数字也必须包含,那么 要么只是包含它自己(arr[i]),或者包含它自己以及之前的数字(include[i - 1] + arr[i])
            include[i] = Math.max(include[i - 1] + arr[i], arr[i]);
            //如果1个delete,那么 要么当前的数字delete(include[i - 1]),要么之前的数字已经delete+当前数字(noInclude[i - 1] + arr[i])
            noInclude[i] = Math.max(noInclude[i - 1] + arr[i], include[i - 1]);
            int temp = Math.max(noInclude[i], include[i]);
            result = Math.max(temp, result);
        }
        // System.out.println(Arrays.toString(noInclude));
        // System.out.println(Arrays.toString(include));
        return Math.max(result, sum);
    }

    //优化dp空间
    public int maximumSum(int[] arr) {
        int noInclude = 0;
        int include = arr[0];
        int result = arr[0];
        for(int i = 1; i < arr.length; i++) {
            int preNoInclude = noInclude, preInclude = include;
            //如果不delete,那么前面数字也必须包含,那么 要么只是包含它自己(arr[i]),或者包含它自己以及之前的数字(include[i - 1] + arr[i])
            include = Math.max(preInclude + arr[i], arr[i]);
            //如果1个delete,那么 要么当前的数字delete(include[i - 1]),要么之前的数字已经delete+当前数字(noInclude[i - 1] + arr[i])
            noInclude = Math.max(preNoInclude + arr[i], preInclude);
            int temp = Math.max(noInclude, include);
            result = Math.max(temp, result);
        }
        return result;
    }
}

 

posted @ 2022-02-20 04:00  xiaoyongyong  阅读(91)  评论(0)    收藏  举报