劍指Offer(Java版):和爲s的兩個數字VS和爲s的連續正數序列

題目一:輸入一個遞增排序的數組和一個數字s,在數組中查找兩個數,使得它們的和正好是s。若是有多個數字的和等於s,輸出任意一對便可。面試

例如輸入數組{1,2,4,7,11,15}和數字15.因爲4+11=15,所以輸出4和11.算法

在面試的時候,很重要的一點是應聘者要表現出很快的反應能力。只要想 到一個辦法,應聘者就能夠立馬告訴面試官,即便這個辦法不必定是最好的。好比這個問題,不少人會當即能想到O(n2)的方法,也就是先在數組中固定一個數 字,再依次判斷數組中其他n-1個數字與它的和是否是等於s。面試官會告訴咱們這不是最好的方法。不過這沒有關係,至少面試官會知道咱們的思惟仍是比較敏 捷的。數組

接着咱們尋找更好的算法。咱們先在數組中選擇兩個數字,若是他們的和 等於輸入的s,咱們就找到了要找的兩個數字。若是小於s呢?咱們但願兩個數字的和再大一點。因爲數組已經排好序了,咱們能夠考慮選擇較小的數字後面的數 字。由於排在後面的數字要大一點,那麼這兩個數字的和也要大一點,就有可能等於輸入的數字s了。一樣,當兩個數字的和大於輸入的數字的時候,咱們就能夠選 擇較大的數字前面的數字了,由於排在前面的數字要小一些。排序

基於上面的思路,咱們實現代碼以下:it

 

package cglib;class

public class jiekou {
    public static void main(String[] args) {
        jiekou p=new jiekou();
        int[] data={1,2,4,7,11,15};
        int sum=15;
        System.out.println(p.findNumberWithSum(data, sum));
        }
    public boolean findNumberWithSum(int[] data,int sum){
        boolean found=false;
        if(data==null)
            return found;
        
        int num1=0;
        int num2=0;
        int start=0;
        int end=data.length-1;
        while(start<end){
        int curSum=data[start]+data[end];
        if(curSum==sum){
        num1=data[start];
        num2=data[end];
        found=true;
        break;
        }
        else if(curSum>sum)
        end--;//當兩個數字的和大於輸入的數字的時候,咱們就能夠選擇較大的數字前面的數字了,由於排在前面的數字要小一些。
        else
        start++;
        }
        System.out.println(num1);
        System.out.println(num2);
        return found;
        }
        }方法

 

輸出:
4
11
true經驗

這種算法的時間複雜度爲O(n)static

 

 

題目二:輸入一個正數s,打印出全部的和爲s的連續正數序列(至少含有兩個數字)。例如輸入15,因爲1+2+3+4+5=4+5+6=7+8=15,因此結果打印出3個連續的序列1——5,4——6,7——8.時間

有了前面的經驗,咱們也考慮用兩個樹small和big分別表示序列 的最小值和最大值。首先把small初始化爲1,big初始化爲2.若是從small到big的序列的和大於s,咱們能夠從序列中去掉較小的值,也就是增 大small的值。若是從small到big的序列的和小於s,咱們能夠增大big,讓這個序列包含更多的數字。由於這個序列至少要有兩個數字,咱們一直 增長small 到(1+s)/2爲止。

Java代碼實現上面的思路:

package cglib;

public class jiekou {
    public static void main(String[] args) {
        jiekou p=new jiekou();
        int sum=15;
        p.findContinuesSequence(sum);
        }
    public void findContinuesSequence(int s){
        if(s<3)
        return;
        int small=1;
        int big=2;
        while(small <(s+1)/2){  
            int curSum = 0;  
            for(int i = small ;i<=big;i++)  
            {
                System.out.println("i="+i);
                curSum +=i;
                System.out.println("curSum="+curSum);
                
            }
            
            System.out.println("此時curSum="+curSum);
            if(curSum == s){  
                System.out.println("find one");  
                printContineNum(small, big);  
                small++;  
            }  
            else{  
                if(curSum > s)  
                    small++;  
                else  
                    big++;  
            }  
        }  
        
    }
    private void printContineNum(int small, int big) {
    for(int i=small;i<=big;i++){
    System.out.print(i+" ");
    }
    System.out.println();
    }
        
        }
   

輸出:

i=1 curSum=1 i=2 curSum=3 此時curSum=3 i=1 curSum=1 i=2 curSum=3 i=3 curSum=6 此時curSum=6 i=1 curSum=1 i=2 curSum=3 i=3 curSum=6 i=4 curSum=10 此時curSum=10 i=1 curSum=1 i=2 curSum=3 i=3 curSum=6 i=4 curSum=10 i=5 curSum=15 此時curSum=15 find one 1 2 3 4 5 i=2 curSum=2 i=3 curSum=5 i=4 curSum=9 i=5 curSum=14 此時curSum=14 i=2 curSum=2 i=3 curSum=5 i=4 curSum=9 i=5 curSum=14 i=6 curSum=20 此時curSum=20 i=3 curSum=3 i=4 curSum=7 i=5 curSum=12 i=6 curSum=18 此時curSum=18 i=4 curSum=4 i=5 curSum=9 i=6 curSum=15 此時curSum=15 find one 4 5 6 i=5 curSum=5 i=6 curSum=11 此時curSum=11 i=5 curSum=5 i=6 curSum=11 i=7 curSum=18 此時curSum=18 i=6 curSum=6 i=7 curSum=13 此時curSum=13 i=6 curSum=6 i=7 curSum=13 i=8 curSum=21 此時curSum=21 i=7 curSum=7 i=8 curSum=15 此時curSum=15 find one 7 8

相關文章
相關標籤/搜索