「ソードフィンガーオファー」-41、およびSの連続ポジティブシーケンス

1.この質問の知識ポイント

ダブルポインタ

2.タイトルの説明

Xiao Mingは数学がとても好きです。ある日、数学の宿題をしているときに、9〜16の合計を計算するように頼みました。彼はすぐに正解は100だと書きました。しかし、彼はこれに満足していませんでした。彼は、連続する正のシーケンスの合計が100になるのか(少なくとも2つの数値を含む)疑問に思っていました。彼が合計100の連続する正の数の別のシーケンスを取得するのにそれほど時間はかかりませんでした:18,19,20,21,22。質問はお任せしますが、合計がSであるすべての連続した正のシーケンスをすばやく見つけることができますか?がんばろう!

合計がSであるすべての連続する正の数を出力します。シーケンス内で最小から最大の順序に従い、シーケンス間で最小から最大の開始番号に従います。

输入:
9
返回值:
[[2,3,4],[4,5]]

3.問題解決のアイデア

この質問では、連続したシーケンスでの連続検索であるため、スライディングウィンドウの上限と下限を見つけるためにダブルポインターを使用するというアイデアと同様のスライディングウィンドウのアイデアを使用できます。現在のシーケンスの最大値と最小値をそれぞれ指すには、2つの数値lowとhighを使用します。

  1. 初期化、低= 1、高= 2
  2. ウィンドウ内の値の合計が目標値の合計よりも小さい場合は、ウィンドウを拡大する必要があることを意味します、高い+ = 1
  3. ウィンドウ内の値の合計が目標値の合計よりも大きい場合は、ウィンドウを小さくする必要があることを意味します、低い+ = 1
  4. それ以外の場合は、目標値と等しくなり、結果を保存して、ウィンドウを縮小します
  5. 質問には少なくとも2つの数値が必要なため、ウィンドウの左端は合計の半分に達したときに終了できます。

4.コード

public class Solution {
    
    
    ArrayList<ArrayList<Integer>> list = new ArrayList<>();

    public ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum) {
    
    
        // 初始化
        int low = 1;
        int high = 2;
        // 窗口左边界走到 sum 的一半即可终止,因为题目要求至少包含 2 个数
        while (low <= sum / 2) {
    
    
            // 窗口中值的和
            int target = (low + high) * (high - low + 1) / 2;
            if (target < sum) {
    
    
                // 如果窗口中值的和小于目标值 sum,表示需要扩大窗口,high += 1
                high++;
            } else if (target > sum) {
    
    
                // 如果窗口中值的和大于目标值 sum,表示需要缩小窗口,low += 1
                low++;
            } else {
    
    
                // 否则,等于目标值,保存结果,缩小窗口
                ArrayList<Integer> temp = new ArrayList<>();
                for (int i = low; i <= high; i++) {
    
    
                    temp.add(i);
                }
                list.add(temp);
                low++;
            }
        }
        return list;
    }
}

おすすめ

転載: blog.csdn.net/bm1998/article/details/113047410