題目:
對於給定正整數數組A和給定正整數T,請在A中找出兩個連續子數組,這兩個子數組不能相交,並且兩個子數組的和相等且為 T。可能會有多種方案,請返回兩個子數組長度和的最小值。如果無法找到這樣的方案,請返回 -1。
思路:
利用滑動窗口,記錄窗口內的和 sum、窗口的左指針 left ,當窗口內的和大於給的 T 值,停下來,利用移動滑動窗口的方式,當 sum > T,將 sum - A[ left ] ,並且將左指針 left 往右移一格,當 sum < T 的時候,停止左邊滑動窗口的移動,變成將滑動窗口的右指針往右移。因為,只需要子數組的長度,所以結果集 res 中,記錄子數組的長度即可。
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class lingMengWeiQu3 { public static void main(String[] args) { int[] nums = {7,3,2,5}; System.out.println(minSumOfLengths(nums, 7)); } public static int minSumOfLengths (int[] A, int T){ if(A == null || A.length == 0) return -1; List<Integer> res = new ArrayList<>(); //存放子數組的長度 int sum = 0, left = 0; // 窗口內的和,窗口的左指針 for(int i = 0; i < A.length; i++){ // i 作為滑動窗口的右指針 sum += A[i]; if(sum >= T){ //窗口內的和 >= T,停下來判斷是否移動窗口、還是加入結果 while(sum >= T){ if(sum > T){ sum -= A[left]; //窗口內的和,減去最左的元素 left += 1; //窗口往右移一格 }else{ //sum == T res.add(i - left + 1); //窗口長度放入結果集 left = i + 1; //窗口左指針重置 sum = 0; //窗口和清零 } } } } if(res.size() < 2) return -1; Collections.sort(res); //結果集排序 return res.get(0) + res.get(1); // 返回最小的2個 } }
注:由於是結束考試后,下來才重新寫的代碼,不知道 OJ 是否能通過,不過感覺應該是沒問題,解題思想是用這個方法。