编程之美2.12 快速寻找满足条件的两个数

//题目:给一个数组,求数组中两个数字之和等于给定数字的元素  
//解法1:穷举法,计算两两元素的和是否满足要求,时间复杂度O(n^2)  
public class Main {  

 public static void main(String[] args) {  
     findNum(new int[]{5,6,8,3,7,9,4},12);  
 }  

 public static void findNum(int[] input, int target) {  
     for(int i = 0;i<input.length;i++){  
         for(int j = i+1;j<input.length;j++){  
             if(input[i]+input[j] == target){  
                 System.out.println(input[i]+" "+input[j]);  
             }  
         }  
     }  
 }  
   
}  

//解法2:先排序,再使数组第一个元素与最后一个元素求和,根据sum与target关系调整low和high的位置,时间复杂度O(NlogN)因为要排序  
public class Main {  

 public static void main(String[] args) {  
     findNum(new int[]{5,6,8,3,7,9,4},12);  
 }  

 public static void findNum(int[] input, int target) {  
     sort(input,0,input.length-1);  
     int low = 0;  
     int high = input.length-1;  
     while(low<high){  
         int sum = input[low]+input[high];  
         if(sum == target){  
             System.out.println(input[low]+" "+input[high]);  
             high--;  
         }else if(sum>target){  
             high--;  
         }else{  
             low++;  
         }  
     }  
 }  
   
 public static void sort(int[] input, int low, int high){  
     if(low<high){  
         int mid = partition(input, low, high);  
         sort(input, low, mid-1);  
         sort(input, mid+1, high);  
     }  
 }  
   
 public static int partition(int[] input, int low, int high){  
     int temp = input[low];  
     while(low<high){  
         while(low<high && input[high]>temp){  
             high--;  
         }  
         input[low] = input[high];  
         while(low<high && input[low]<temp){  
             low++;  
         }  
         input[high] = input[low];  
     }  
     input[low] = temp;  
     return low;  
 }  

}  

//解法3:hash表,以空间换时间,时间复杂度O(N),空间复杂度O(N)  
public class Main {  

 public static void main(String[] args) {  
     findNum(new int[]{5,6,8,3,7,9,4},12);  
 }  

 public static void findNum(int[] input, int target) {  
     HashSet<Integer> hash = new HashSet<Integer>();  
     HashSet<Integer> hash1 = new HashSet<Integer>();    //避免重复,3+9 = 12,9+3 = 12  
     for(int i = 0;i<input.length;i++){  
         if(!hash.contains(input[i])){  
             hash.add(input[i]);  
         }  
     }  
     for(int i = 0;i<input.length;i++){  
         int value = target-input[i];  
         hash.remove(input[i]);                  //防止6+6 = 12这种情况发生  
         if(!hash1.contains(value) && hash.contains(value)){  
             System.out.println(input[i]+" "+value);  
         }  
         hash.add(input[i]);  
         hash1.add(input[i]);  
     }  
 }  
   
}

// 扩展题目:给一个数组,求其中n个数字和为指定数字的n个元素
// 解法:按照循环的方式找前n-2个元素,最后两个元素用之前的方法找
public class Main {

	public static void main(String[] args) {
		List<List<Integer>> result = new ArrayList<List<Integer>>();
		List<Integer> temp = new ArrayList<Integer>();
		findNum(new int[]{1,2,3,4,5,6,7,8,9},20,4,temp,result);
		for(int i = 0;i<result.size();i++){
			printList(result.get(i));
		}
	}

	public static void findNum(int[] input, int target, int n, List<Integer> temp,List<List<Integer>> result) {
		if(n == 2){
			int low = 0;
			int high = input.length-1;
			while(low<high){
				if(target == input[low]+input[high]){
					temp.add(input[low]);
					temp.add(input[high]);
					if(!isContain(result,temp)){
						result.add(new ArrayList<Integer>(temp));
					}
					return;
				}else if(target > input[low]+input[high]){
					low++;
				}else{
					high--;
				}
			}
			return;
		}else{
			for(int i = 0;i<input.length;i++){
				temp.add(input[i]);
				int[] input_temp = copyarry(input,i);
				findNum(input_temp,target-input[i],n-1,temp,result);
				if(temp.size() == 4){
					temp.remove(temp.size()-1);
					temp.remove(temp.size()-1);
					temp.remove(temp.size()-1);
				}else{
					temp.remove(temp.size()-1);
				}
			}
		}
	}
	
	private static int[] copyarry(int[] arry, int i) {  	//在数组中删除出现过的元素
        int[] tmp = new int[arry.length - 1];  
        int idx = 0;  
        for (int j = 0; j < arry.length; j++) {  
  
            if (j != i) {  
                tmp[idx++] = arry[j];  
            }  
        }  
        return tmp;  
    }  
	
	public static void printList(List<Integer> list){		//打印列表中元素
		for(int i = 0;i<list.size();i++){
			System.out.print(list.get(i)+" ");
		}
		System.out.println();
	}
	
	public static boolean isContain(List<List<Integer>> result, List<Integer> temp){		//判断result中是否有与temp一样的组合出现
		for(int i = 0;i<result.size();i++){
			List<Integer> t = new ArrayList<Integer>();
			for(int j = 0;j<result.get(i).size();j++){
				t.add(result.get(i).get(j));
			}
			for(int j = 0;j<temp.size();j++){
				if(t.contains(temp.get(j))){
					t.remove(temp.get(j));
				}
			}
			if(t.size() == 0){
				return true;
			}
		}
		return false;
	}
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Apache Flink是一个流式处理框架,支持使用Scala和Java等多种语言进行编程。Scala是Flink主要支持的语言之一,目前Flink分别提供了Scala 2.11和Scala 2.12个版本。 Scala 2.12是Scala 2.x系列的最新版本,它与之前的Scala 2.11相比,在语言特性、性能和库的兼容性方面都有所改进。具体来说,Scala 2.12相较于2.11版本有以下一些不同点: 1. 集合库的改进:Scala 2.12提供了一个全新的集合库(Collections Library),其中包含了许多新的集合类型,如ArrayOps、StringOps等。此外,还对现有集合类型进行了优化,提升了性能。 2. 可以使用Java 8中的新特性:Scala 2.12Java 8的新特性提供了支持,包括Lambda表达式和方法引用等。 3. 二进制文件格式的改变:Scala 2.12使用了新的二进制文件格式,它支持Java 9中的新特性,并且与Java 8和Java 9之间的兼容性更好。 4. 性能提升:Scala 2.12通过一系列的优化,如编译器的改进和库的重构等,提升了运行时的性能。 总的来说,Scala 2.12相较于Scala 2.11更加先进和高效,但是由于二进制文件格式的改变,需要注意与之前版本的兼容性。在使用Flink时,可以根据具体的需求和环境选择合适的Scala版本。 ### 回答2: Flink是一个用于大规模流处理和批处理的开源分布式计算框架。主要用于处理实时数据流以及批量数据。Flink提供了Scala API,支持不同版本的Scala语言,包括Scala 2.11和Scala 2.12。这个版本在语言特性和兼容性方面有一些区别。 首先,Scala 2.12是Scala编程语言的较新版本,相较于Scala 2.11,Scala 2.12引入了一些新特性和改变。其中一个重要的变化是对Java 8中的新特性的更好支持,包括lambda表达式和函数式接口。因此,如果你打算在Flink中使用lambda表达式或函数式编程风格,可能会发现Scala 2.12更加方便。 另一个区别是在库和依赖方面的兼容性。Scala 2.11和Scala 2.12使用不同的二进制兼容模式,这意味着如果你使用某个库或依赖是针对Scala 2.11编译的,它可能与Scala 2.12不兼容。在Flink的生态系统中,有些库可能只提供Scala 2.11的版本,而对Scala 2.12的支持较为有限。因此,在选择Flink版本时,需要考虑到项目中的其他依赖,并确保它们与所选版本兼容。 总之,Scala 2.11和Scala 2.12个版本在语言特性和兼容性方面存在一些区别。选择哪个版本取决于你的项目需求、代码库的兼容性以及个人偏好。 ### 回答3: Flink是一个开源的分布式实时计算框架,具有高效和灵活的特点。在Flink的版本迭代过程中,Scala是其主要的编程语言之一,Scala 2.11版本和Scala 2.12版本在使用上存在一些区别。 首先,Scala 2.12是Scala的一个最新版本,相对于Scala 2.11,它引入了一些新的特性和优化。比如,Scala 2.12Java 8的支持更好,提供了更多有用的函数式编程特性。同时,Scala 2.12在编译速度和运行时性能方面也有一些优化,能够更好地支持Flink的大规模实时计算。 其次,由于Scala 2.12引入了一些语法上的改变,因此Flink的某些组件在Scala 2.11和Scala 2.12之间可能存在不兼容的情况。在使用Scala 2.12时,需要确保所使用的Flink版本兼容Scala 2.12,否则可能会出现编译或运行时的错误。 此外,由于Scala 2.12相对于Scala 2.11是一个较新的版本,目前在一些第三方库和组件的支持上可能不如Scala 2.11完善。因此,在选择使用哪个版本时,需要考虑到项目所依赖的其他库和组件是否支持Scala 2.12。 综上所述,Scala 2.11和Scala 2.12在Flink中主要区别在于语言特性、性能优化和兼容性方面。具体选择哪个版本取决于项目的需求和所依赖的其他库和组件的支持情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值