[剑指Offer]57-和为s的数字
题目一
输入一个递增的数组和一个数字,在数组中查找2个数字,是他们的和正好为S,如果有多对的和为S,则输出任意一对即可。
题解
关键信息是数组有序。初始化i,j指向第一个和第二个数,与S比较,若小了,--j,若大了,++i。舍弃掉的元素表示它再也不能和别的数相加等于目标数了,充分利用了有序性。时间复杂度O(n)。
代码
import java.util.ArrayList;
public class Main {
public static void main(String args[]) {
int[] arr= {1,2,4,7,11,15};
int sum=15;
ArrayList<Integer> ansList=findNumbersWithSum(arr,sum);
if(ansList!=null) {
System.out.println(ansList);
}
else {
System.out.println("none");
}
}
public static ArrayList<Integer> findNumbersWithSum(int [] array,int sum) {
if(array.length<2) {
return null;
}
int i=0;
int j=array.length-1;
while(i<j) {
if(array[i]+array[j]==sum) {
break;
}
else if(array[i]+array[j]<sum) {
++i;
}
else {
--j;
}
}
if(i!=j) {
ArrayList<Integer> list=new ArrayList<>();
list.add(array[i]);
list.add(array[j]);
return list;
}
else {
return null;
}
}
}
题目二
输入一个正数s,打印出所有和为s的连续正数序列(至少包含2个数。
题解
- 利用题目一的思路,只不过注意本题是连续个数>=2个数即可。初始化num1=1,num2=2,num1代表较小的数。和目标和比较,若大了++num2,等于在和上+了num2;若小了++num1,等于在和上-了num1。
- 注意终止条件是num1<(1+s)/2。
- 自己算的时间复杂度应该是O(n^2)。
代码
import java.util.ArrayList;
public class Main {
public static void main(String args[]) {
int sum=15;
ArrayList<ArrayList<Integer>> list=findContinuousSequence(sum);
if(list!=null) {
for(ArrayList<Integer> seq:list) {
for(int num:seq) {
System.out.print(num);
}
System.out.println("\n");
}
}
else {
System.out.print("null");
}
}
public static ArrayList<ArrayList<Integer>> findContinuousSequence(int sum) {
if(sum<3) {
return null;
}
int i=1;
int j=2;
int s=i+j;
ArrayList<ArrayList<Integer>> sequenceList=new ArrayList<>();
while(i<(1+sum)/2) {//
if(s==sum) {
sequenceList.add(getAnsList(i,j));
++j;
s+=j;
}
else if(s<sum) {
++j;
s+=j;
}
else {
s-=i;//注意顺序
++i;//
}
}
return sequenceList;
}
public static ArrayList<Integer> getAnsList(int i,int j){
ArrayList<Integer> list=new ArrayList<>();
for(int num=i;num<=j;++num) {
list.add(num);
}
return list;
}
}
posted on 2019-06-26 12:56 coding_gaga 阅读(142) 评论(0) 编辑 收藏 举报