剑指offer--41.和为s的两个数字和为s的连续正数序列

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

分析:在数组中固定一个数字,再依次判断数组中其余n-1个数字与它的和是否为s,时间复杂度为O(n^2)。在数组中选择两个数字,如果它们的和等于s,我们即找到了这两个数字;如果和小于s,选择较小的数字后面的数字;如果和大于s,选择较大的数字后面的数字。时间复杂度O(n)

题目二:输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数)

分析:可设置两个指针,分别指向序列的最小值low和最大值high,如果从low到high的和大于s,可以从序列中去掉最小值,即增大low;如果从low到high的和小于s,可以增大high,让序列包含更多的数字

题目三:牛客上对一进行了改进,即输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出乘积最小的两个数

import java.util.*;
public class wr41FindContinuousSequence {
//	题目一:查找两个数,和为s,若有多对,输出任意一对即可
//	方法一,固定,遍历,O(n^2)
	public static ArrayList<Integer> findTwo(int []array,int sum){
		ArrayList<Integer> list=new ArrayList<>();
		for(int i=0;i<array.length;i++){
			for(int j=i+1;j<array.length;j++){
				if(array[i]+array[j]==sum){
					list.add(array[i]);
					list.add(array[j]);
					break;
				}
			}
		}
		return list;
	}
//	方法二,在数组中选择两个数字,计算其和,根据其和sum的关系,调整扫描策略
	public static ArrayList<Integer> findTwoBetter(int []array,int sum){
		 ArrayList<Integer> list=new ArrayList<>();
		 int i=0;
		 int j=array.length-1;
		 while(i<j){
			 if(array[i]+array[j]==sum){
				 list.add(array[i]);
				 list.add(array[j]);
				 break;
			 }
			 else if(array[i]+array[j]>sum){
				 j--;
			 }
			 else{
				 i++;
			 }
		 }
		 return list;
	}
//	题目二:和为s的连续正数序列
	public static ArrayList<ArrayList<Integer>> FindContinuousSequence(int sum){
		ArrayList<ArrayList<Integer>> result=new ArrayList<>();
		int low=1;
		int high=2;
		while(low<high){
			int curSum=(low+high)*(high-low+1)/2;
			if(curSum==sum){
				ArrayList<Integer> list=new ArrayList<>();
				for(int i=low;i<=high;i++){
					list.add(i);
				}
				result.add(list);
				high++;
			}
			else if(curSum<sum){
				high++;
			}
			else{
				low++;
			}
		}
		return result;
	}
//	题目三:和为s的两个数,若有多对,输入乘积最小的
	 public static ArrayList<Integer> FindNumbersWithSum(int [] array,int sum){
		 ArrayList<Integer> list=new ArrayList<>();
		 int i=0;
		 int j=array.length-1;
		 while(i<j){
			 if(array[i]+array[j]==sum){
				 if(!list.isEmpty()){
					 int multi=list.get(0)*list.get(1);
					 int temp=array[i]*array[j];
					 if(temp<multi){
						 list.clear();
						 list.add(array[i]);
						 list.add(array[j]);
					 }
				 }
				 else{
					 list.add(array[i]);
					 list.add(array[j]);
				 }
				 i++;
			 }
			 else if(array[i]+array[j]>sum){
				 j--;
			 }
			 else{
				 i++;
			 }
		 }
		 return list;
	 }

	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		int []array={1,2,4,7,11,15};
//		ArrayList<Integer> list=findTwo(array,15);
//		ArrayList<Integer> list=findTwoBetter(array,15);
//		for(int i:list){
//			System.out.print(i+" ");
//		}
//		System.out.println();
		
//		ArrayList<ArrayList<Integer>> result=FindContinuousSequence(15);
//		for(int i=0;i<result.size();i++){
//			System.out.println(result.get(i));
//		}
		
		int []a={1,2,4,7,8,11,15};
		ArrayList<Integer> listMin=FindNumbersWithSum(a,15);
		for(int i:listMin){
			System.out.print(i+" ");
		}
	}

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值