劍指Offer的學習筆記(C#篇)-- 和爲S的連續正數序列

題目描述

小明很喜歡數學,有一天他在作數學做業時,要求計算出9~16的和,他立刻就寫出了正確答案是100。可是他並不知足於此,他在想究竟有多少種連續的正數序列的和爲100(至少包括兩個數)。沒多久,他就獲得另外一組連續正數和爲100的序列:18,19,20,21,22。如今把問題交給你,你能不能也很快的找出全部和爲S的連續正數序列? Good Luck!

一 . 分析題目

        該題目有幾個點須要注意一下:算法

        1 . 這個鏈表是連續的正數序列,且最少爲兩個數。數組

        2 . 因爲1中的特性,因此數組的和能夠用公式計算。(1加到100的那種方法求和,即爲:(1+100)*100 / 2)。spa

        貌似題目也只有這兩個點須要注意,接下來就是核心算法了,三個概念:1.數組內的數。2.數組實際和。3. 數組目標和。code

        當數組實際和=目標和時,爲了繼續尋找能夠實現目標和的數組,須要把小數和大數都前移1位;blog

        當數組實際和>目標和時,把小數往前移一位,這樣數組內的數就少了最小的一個數,在作比較。數學

        當數組實際和<目標和時,把大數往前移一位,這樣數組內的數就增長了一個大數,再比比啊。it

二 . 代碼實現

using System.Collections.Generic;
class Solution
{
    public List<List<int>> FindContinuousSequence(int sum)
    {
        // write code here
        // 定義最終輸出數組
        List<List<int>> ret = new List<List<int>>();
        // 定義i=1,j=2,緣由:
        int i = 1, j = 2;
        // 方法中止條件:1.由於最終輸出數組最少爲2個數,因此小的那個數不能超過sum的一半,超過了相加就大於sum了,並且小數必須小於大數
        while(i < (sum + 1) / 2 && i < j)
        {
            // 由於是連續的數,因此求和公式能夠爲(小數+大數)*長度/2;(舉例:1加到100怎麼算)
            int tmpSum = (i + j) * (j - i + 1) / 2;
            // 要是數組和小於目標數,須要讓大數增長如下
            if(tmpSum < sum)
            {
                j++;
            }
            // 相等就輸出咯
            else if(tmpSum == sum)
            {
                // 定義一個數組,數組長度就是i-j之間的長度
                int[] ary = new int[j - i + 1];
                // 執行循環,得出數組從i-j
                for(int k = i, l = 0; k <= j; k++, l++)
                {
                    ary[l] = k;
                }
                // 這個數組添加到定義的那個鏈表
                ret.Add(new List<int>(ary));
                // 若是還存在其餘的怎麼辦呢,因此要執行i++h和j++
                i++;
                j++;
            }
            // 要是數組和大於目標數,把小數加1,這樣數組裏的數就變少了對吧
            else
            {
                i++;
            }
        }
        // 返回那個鏈表
        return ret;
    }
}
相關文章
相關標籤/搜索