問題描述:
給定乙個含有 n 個正整數的陣列和乙個正整數 s ,找出該陣列中滿足其和 ≥ s 的長度最小的連續子陣列。如果不存在符合條件的連續子陣列,返回 0。
示例:
輸入: s = 7, nums = [2,3,1,2,4,3]
輸出: 2
解釋: 子陣列 [4,3] 是該條件下的長度最小的連續子陣列
演算法一:二分查詢
先構建乙個sums陣列,sums[i]為從0到i的元素之和。
並且有如下結論:
i到j之間元素之和 sum= sums[j] - sums[i] + nums[i]
由於想要找到sum >= a的問題可以轉化為:找 sums[j] >= a + sums[i] - nums[i] = target的問題,
如此就可以採用二分查詢的方式從sums中找到不小於target的第乙個元素。
實現**如下:
public static int minsubarraylen(int s, int nums)
// 找到從i到n-1滿足條件的解
for (int i = 0; i < sums.length; i++)
int left = i, right = sums.length -1, mid;
int temp = s + sums[i] - nums[i];
int optindex = binsearch(sums, temp, left, right);
result = math.min(result, optindex - i + 1);
}return result == nums.length + 1 ? 0 : result;}/*
* find sums[i] >= target first i
*/public static int binsearch(int sums, int target, int left, int right) else
}if (sums[left] >= target)
if (sums[right] >= target)
return -1;
}
該演算法的時間複雜度為o(nlogn),額外空間複雜度為o(n)。
演算法二:雙指標+滑動窗
兩個指標乙個指向窗頭,乙個指向窗尾,並且維護窗內的元素之和大於等於a,並且長度最短。
判斷窗類元素是否大於等於a,若滿足則更新結果,並把頭指正右移;否則移動尾指標。迭代上述過程直到尾指標到最後乙個元素為止。
實現**如下:
public static int doublepointer(int s, int nums) else
}return result == nums.length + 1 ? 0 : result;
}
該演算法由於只遍歷一次,並且對於sum的計算都是o(1)的因此時間複雜度為o(n),由於只使用有限個中間變數,其額外空間複雜度為o(1)。 二分查詢的平均查詢長度 二分查詢
資料的查詢在計算機的操作中非常常見,那麼我們應該怎樣在計算機中實現查詢操作呢?最簡單的一種方法 傻找 也就是乙個乙個的找,我們把陣列中的每個元素都和我們想要查詢的目標元素進行比對,看一下列表中是否有和這個元素相同的元素,如果我們想要尋找的那個目標元素在列表 現了,那麼就宣告查詢成功,這種演算法寫成 ...
陣列的二分查詢
public class myorderarray public myorderarray int maxsize 新增有序陣列 public void insert long value 比如在2456這個陣列中查入3,那456要整體向後移動,從6後面開始操作 for int j elemnet ...
二分查詢和遞迴的二分查詢
在乙個有序的陣列中查詢給定的資料項,把陣列衝中間分成兩半,然後看要查詢的資料項在陣列的哪一半,再次折半查詢。如下 public int find long searchkey else if lowerbound upperbound else private int recfind long se...