剑指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

相关文章
相关标签/搜索