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

}

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Autumn03/article/details/80357134
个人分类: 剑指offer-java实现
上一篇剑指offer--40.数组中只出现一次的数字
下一篇剑指offer--42.翻转单词顺序VS左旋字符串
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭