325. Maximum Size Subarray Sum Equals k (Medium) 考简化版

Given an array nums and a target value k, find the maximum length of a subarray that sums tok. If there isn't one, return 0 instead.

Note:
The sum of the entire nums array is guaranteed to fit within the 32-bit signed integer range.

Example 1:

Given nums=[1, -1, 5, -2, 3],k=3,
return4. (because the subarray[1, -1, 5, -2]sums to 3 and is the longest)

Example 2:

Given nums=[-2, -1, 2, 1],k=1,
return2. (because the subarray[-1, 2]sums to 1 and is the longest)

Follow Up:
Can you do it in O(n) time?

Solution 1: HashMap + Prefix Sum Array O(n); O(n)

和209比较:这两道题的解法完全不同:这道题由于是求“equal”,所以用“hash”;上一题是求“大于等于”,所以是用two pointers尺取法。而且由于两道题的要求不同,它们的输入数据也不同:这道题的输入数据可正可负;上一题却只能是非负数。

    public int maxSubArrayLen(int[] nums, int k) {
        if (nums == null) {
            return 0;
        }

        Map<Integer, Integer> map = new HashMap<>();
        map.put(0, -1); // start from sum = 0, where is a virtual index of -1.
        int sum = 0;
        int res = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i]; //store prefix sum, which is the sum of first i elements
//            if (sum == k) { //can be replaced by map.put(0, -1)
//                max = i + 1;
//            } else
            if (map.containsKey(sum - k)) {
                res = Math.max(res, i - map.get(sum - k));
            }

            if (!map.containsKey(sum)) {
                map.put(sum, i);
            }
        }
        return res;
    }
Follow Up:

1.简化版:只需要判断是否存在,返回boolean,用一个set做就可以,我一上来傻乎乎的写了map。。

1,2,3,4,5 维持当前和1,3,6,10,15, 如果当前和为k或者当前和减去之前的一个和为k,则返回true。。。

    /**
     * 简化版 if array exists Subarray Sum Equals k
     * HashSet O(n);O(n)
     * 如果只有非负数,可以用LC 209 Minimum Size Subarray Sum的双指针方法做,空间是O(1).
     */    
    public boolean subarraySum(int[] nums, int k) {
        if (nums == null) {
            return false;
        }

        Set<Integer> set = new HashSet<>();
        int sum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            if (sum == k || set.contains(sum - k)) {
                return true;
            }

            if (!set.contains(sum)) {
                set.add(sum);
            }
        }
        return false;
    }
  • 后来让改用constant space,就用了sliding window
    /**
     * 如果只有非负数,可以用LC 209 Minimum Size Subarray Sum的双指针方法做,空间是O(1).
     * Two Pointers O(n); O(1)
     */
    public boolean subarraySumB(int[] nums, int k) {
        if (nums == null || nums.length == 0) {
            return false;
        }

        int sum = 0; //important
        int left = 0;
        //right pointer moves, left pointer stops until while loop starts
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            if (sum == k) { //right pointer stops, left pointer moves
                return true;
            }
            if (sum > k) {
                sum -= nums[left];
                left++;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        MaximumSizeSubarraySumEqualsk test = new MaximumSizeSubarraySumEqualsk();
        int[] nums = {3, 2, 3, 1};
        System.out.println(test.subarraySumB(nums, 9));
    }

results matching ""

    No results matching ""