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