長度最小的子陣列(二分查詢 和 雙指標滑動窗)

2021-09-29 18:18:05 字數 1495 閱讀 9512

問題描述:

給定乙個含有 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...