Subarray子數組

該題型多采用prefixSum的方法:

(一)Maximum Subarray (Frequent ++)

https://leetcode.com/problems/maximum-subarray/description/

題目:找到數組中總和最大的子集並返回該子集總和;

解答:從頭到尾依次遍歷數組,實時記錄最大的sum值和最小的sum值。每次只需比較當前最大值和當前sum-最小sum的值,即可更新最大sum值。

改進:可以把求prefixSum的循環和找最大的循環合併成一個

代碼:

class Solution {
    public int maxSubArray(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        int max = Integer.MIN_VALUE;
        int sum = 0;
        int minSum = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            max = (sum - minSum) > max ? (sum - minSum) : max;
            minSum = sum < minSum ? sum : minSum;
        }
        return max;
    }
}


(二)Subarray Sum Equals K

https://leetcode.com/problems/subarray-sum-equals-k/description/

題目:找到和爲K的子集並返回滿足該條件子集的個數;

解答:先將元素組變成累加和的數組,再依次遍歷並比較;

代碼:
class Solution {
    public int subarraySum(int[] nums, int k) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        
        int res = 0;
        
        for (int i = 1; i < nums.length; i++) {
            nums[i] += nums[i - 1];
        }
        for (int i = 0; i < nums.length; i++) {
             if (nums[i] == k) {
                 res++;
             }
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[j] - nums[i] == k) {
                   res++;
                }
            }
        }
        return res;
    }
}

(三)Subarray Sum closest 

http://www.lintcode.com/en/problem/subarray-sum-closest/

題目:找出數組中子集和最接近0的首、尾index;

解答:將序列index和對應的prefixSum存在map中,將prefixSum單獨存在一個序列裏,將該序列排序,依次比較相鄰元素將差值較小的元素序列號提取出來,比較大小,依次更新res[0]和res[1]。

第一次犯錯:時間複雜度太高,超時;

第二次犯錯:使用map,prefixSum相同的元素會覆蓋,導致結果錯誤;
解答:當prefixSum存在相同元素時,說明存在子數列和爲0,故無需覆蓋,直接返回首位值即可;

第三次犯錯:單獨把最後一個元素加入map時,忘記判斷該元素是否已存在於序列中(循壞未覆蓋,需單獨判斷)

代碼:
public class Solution {
    /**
     * @param nums: A list of integers
     * @return: A list of integers includes the index of the first number 
     *          and the index of the last number
     */
    public int[] subarraySumClosest(int[] nums) {
        // write your code here
        int[] res = new int[2];
        int[] prefixSum = new int[nums.length + 1];
        int diff = Integer.MAX_VALUE;
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; i++) {
           prefixSum[i + 1] = prefixSum[i] + nums[i];
           if (!map.containsKey(prefixSum[i])) {
               map.put(prefixSum[i], i);
            } else {
                res[0] = map.get(prefixSum[i]);
                res[1] = i - 1;
                return res;
            }
        }
        
        if (!map.containsKey(prefixSum[nums.length])) {
            map.put(prefixSum[nums.length], nums.length);
        } else {
            res[0] = map.get(prefixSum[nums.length]);
            res[1] = nums.length - 1;
            return res;
        }
        
        Arrays.sort(prefixSum);
        for (int i = 1; i < nums.length + 1; i++) {
            if (prefixSum[i] - prefixSum[i - 1] < diff) {
                int i1 = map.get(prefixSum[i]);
                int i2 = map.get(prefixSum[i - 1]);
                diff = prefixSum[i] - prefixSum[i - 1];
                res[0] = Math.min(i1, i2);
                res[1] = Math.max(i1, i2) - 1;
            }
        }
        return res;
    }
}


發佈了27 篇原創文章 · 獲贊 2 · 訪問量 7126
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章