A-和为s的两个数字VS和为s的连续正数序列

题目41-1:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,输出任意一对即可。
分析:
  先选定第一个数字,然后将后面的数字依次遍历求和,并与需要的数字比较,需要n-1次,如果第一个数字不行,选择第二个,依次遍历求和。。。。需要n^2次,时间复杂度比较高,但也是可以的,在面试中,如果没有更好的办法写这个也是可以的,毕竟要比交白卷好得多,这里不展示此代码。
  由于数组已经是排好序的,可以定义两个指针,第一个指向第一个元素,第二个指向最后一个元素;先拿第一个元素和最后一个元素相加,与要求的数字进行比较,如果大于,则将第二个指针向后移一位(索引值-1),再求和进行比较;如果小于,则将第一个指针向前移一位(索引值+1),再进行求和比较;直至找到结果。时间复杂度为O(n)。
  代码如下所示:

    public static int[] findNumberWithSum(int[] array, int sum) {
        int[] result = new int[2];
        if (array == null || array.length < 2 || sum < 0) {
            return result;
        }
        int start = 0, end = array.length - 1;
        while (start < end) {
            long temp = array[start] + array[end];
            if (temp == sum) {
                result[0] = array[start];
                result[1] = array[end];
                return result;
            } else if (temp > sum) {
                end--;
            } else {
                start++;
            }
        }
        return result;
    }

    public static void main(String[] args) {
//        int[] result = findNumberWithSum(new int[]{1, 3, 5, 7, 8, 3, 5}, 10);
//        int[] result = findNumberWithSum(new int[]{1, 3, 5, 7, 8, 3, 5}, 100);
        int[] result = findNumberWithSum(new int[]{}, 10);
        for (int r : result) {
            System.out.print(r + " ");
        }
    }

题目41-2:输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)。例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1~5、5~6和7~8
分析:
  用两个数small和big分别表示序列的最小值和最大值。首先把small初始化为1,big初始化为2。如果从small到big的序列的和大于s,我们可以从序列中去掉较小的值,也就是增大small的值。如果从small到big的序列的和小于s,我们可以增大big,让这个序列包含更多的数字。因为这个序列至少要有两个数字,我们一直增加small 到(1+s)/2为止。
  以求和为9 的所有连续序列为例,过程如下表所示:

步骤smallbig序列序列和与s相比下一步操作
1121,23小于增加big
2131,2,36小于增加big
3141,2,3,410大于增加small
4242,3,49等于打印序列,增加big
5252,3,4,514大于增加small
6353,4,512大于增加small
7454,59等于打印序列

  代码如下所示:

    public static void findContinuousSequence(int sum) {
        if (sum < 3) return;
        int small = 1, big = 2, middle = (sum + 1) / 2, cur = small + big;
        while (small < middle) {
            if (cur == sum) findContinuousSequence(small, big);
            while (cur > sum && small < middle) {
                cur -= small;
                small++;
                if (cur == sum) findContinuousSequence(small, big);
            }
            big++;
            cur += big;
        }
    }

    public static void findContinuousSequence(int small, int big) {
        for (int i = small; i <= big; i++) {
            System.out.print(i + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        findContinuousSequence(9);
        System.out.println("-------------");
        findContinuousSequence(4);
        System.out.println("-------------");
        findContinuousSequence(3);
    }

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值