和为s的数字

剑指offer57

描述:

输入一个递增排序的数组和一个数字s,在数组中查找两个数,
使得他们的和正好是s,如果有多对数字的和等于s,
则输出任意一对即可

package com.meituan.offer;

import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 * @author tangxuejun
 * @version 2018/9/28 9:20 PM
 */
public class Offer57 {
    @Test
    public void fun1() {
        int[] arr = {1, 2, 4, 7, 11, 15};
        int s = 88;

        System.out.println(this.displayDouble(arr, s));
    }

    /**
     * 输入一个递增排序的数组和一个数字s,在数组中查找两个数,
     * 使得他们的和正好是s,如果有多对数字的和等于s,
     * 则输出任意一对即可
     *
     * @param arr
     * @param s
     * @return
     */
    private String displayDouble(int[] arr, int s) {
        //去除掉比目标数字大的数字
        List<Integer> realList = Arrays.stream(arr)
                .filter(x -> x < s)
                .boxed()
                .collect(toList());
        int start = 0;
        int end = realList.size() - 1;
        while (end > start) {
            //挑选前面一个和最后一个开始匹配
            if (realList.get(start) + realList.get(end) == s) {
                return "找到了" + "(" + realList.get(start) + "," + realList.get(end) + ")";
            }
            //先从后面开始循环,如果后面一个加前面一个大于s,则指针开始从前边移动
            if (realList.get(start) + realList.get(end) < s) {
                start++;
            } else {
                end--;
            }
        }
        return "找不到";
    }


    @Test
    public void fun2() {
        System.out.println(this.displayCoutinuous(15));
    }


    /**
     * 输入一个正数s,打印出所有和为s的连续正数序列,(至少有两个数)
     *
     * @param s
     * @return
     */
    public String displayCoutinuous(int s) {
        List<Integer> collect = Stream
                .iterate(1, x -> x + 1)
                .limit(s)
                .collect(toList());
        StringBuilder sb = new StringBuilder();
        int sum = 0;
        int count = 0;
        for (int i = 0; i < collect.size() - 1; i++) {
            sum += collect.get(i);
            count++;
            if (sum > s) {
                if (count > 2) {
                    i -= 2;
                } else {
                    i--;
                }
                count = 0;
                sum = 0;
            }
            if (sum == s) {
                if (count >= 2) {
                    sb.append(" ").append(i).append(" ");
                }
                //如果count>2则后退两步
                if (count > 2) {
                    //sum重置为0
                    i = i - 2;
                } else {
                    //后退1步
                    i--;
                }
                sum = 0;
                count = 0;
            }
        }
        return sb.toString();
    }
}

第二个小题代码写的有点恶心。。。。有时间再重构下
时间复杂度:O(n);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值