算法导论Java实现-二分查找运用(习题2.3-7)

简介:

 
 
  1. package lhz.algorithm.chapter.two; 
  2.  
  3. /** 
  4.  * 《算法导论》,习题2.3-7  
  5.  * Describe a Θ(n lg n)-time algorithm that, given a set S of n 
  6.  * integers and another integer x, determines whether or not there exist two 
  7.  * elements in S whose sum is exactly x. 
  8.  * @author lihzh(苦逼coder) 
  9. * 本文地址:http://mushiqianmeng.blog.51cto.com/3970029/732739  
  10. */ 
  11. public class Excercise237 { 
  12.  
  13.     private static int[] input = new int[] { 21549867103 }; 
  14.     private static int sum = 11
  15.  
  16.     public static void main(String[] args) { 
  17.         // 先利用合并排序,将给定数组排好序 
  18.         mergeSort(input);// 复杂度:Θ(nlgn) 
  19.         boolean isExist = false
  20.         // 设置循环结束位,每次找到符合条件的元素后,改变循环结束条件 
  21.         // 否则会出现11 = 1 + 10,11 = 10 + 1的重复情况。 
  22.         int end = input.length; 
  23.         for (int i = 0; i < end; i++) {// 复杂度:Θ(n) 
  24.             int temp = sum - input[i]; 
  25.             // 利用二分查找,查询temp是否在数组中。 
  26.             Integer index = binarySearch(input, temp, 0, input.length - 1);// 复杂度:Θ(lgn) 
  27.             if (index != null && index != i) {// 不等于本身 
  28.                 System.out.println(sum + " = " + input[i] + " + " + temp); 
  29.                 end = index; 
  30.                 isExist = true
  31.             } 
  32.         } 
  33.         if (!isExist) { 
  34.             System.out.println("数组不存在两个数的和为:" + sum); 
  35.         } 
  36.         /* 
  37.          * 复杂度分析: 由注释可见,复杂度为:Θ(nlgn) 
  38.          */ 
  39.     } 
  40.  
  41.     /** 
  42.      * 合并排序,复杂度:Θ(nlgn) 
  43.      *  
  44.      * @param array 
  45.      * @return 
  46.      */ 
  47.     private static int[] mergeSort(int[] array) { 
  48.         // 如果数组的长度大于1,继续分解数组 
  49.         if (array.length > 1) { 
  50.             int leftLength = array.length / 2
  51.             int rightLength = array.length - leftLength; 
  52.             // 创建两个新的数组 
  53.             int[] left = new int[leftLength]; 
  54.             int[] right = new int[rightLength]; 
  55.             // 将array中的值分别对应复制到两个子数组中 
  56.             for (int i = 0; i < leftLength; i++) { 
  57.                 left[i] = array[i]; 
  58.             } 
  59.             for (int i = 0; i < rightLength; i++) { 
  60.                 right[i] = array[leftLength + i]; 
  61.             } 
  62.             // 递归利用合并排序,排序子数组 
  63.             left = mergeSort(left); 
  64.             right = mergeSort(right); 
  65.             // 设置初始索引 
  66.             int i = 0
  67.             int j = 0
  68.             for (int k = 0; k < array.length; k++) { 
  69.                 // 如果左边数据索引到达边界则取右边的值 
  70.                 if (i == leftLength && j < rightLength) { 
  71.                     array[k] = right[j]; 
  72.                     j++; 
  73.                     // 如果右边数组索引到达边界,取左数组的值 
  74.                 } else if (i < leftLength && j == rightLength) { 
  75.                     array[k] = left[i]; 
  76.                     i++; 
  77.                     // 如果均为到达则取,较小的值 
  78.                 } else if (i < leftLength && j < rightLength) { 
  79.                     if (left[i] > right[j]) { 
  80.                         array[k] = right[j]; 
  81.                         j++; 
  82.                     } else { 
  83.                         array[k] = left[i]; 
  84.                         i++; 
  85.                     } 
  86.                 } 
  87.             } 
  88.         } 
  89.         return array; 
  90.     } 
  91.  
  92.     /** 
  93.      * 二分查找,复杂度Θ(lg n) 
  94.      *  
  95.      * @param input 
  96.      * @param target 
  97.      * @param from 
  98.      * @param to 
  99.      * @return 
  100.      */ 
  101.     private static Integer binarySearch(int[] input, int target, int from, 
  102.             int to) { 
  103.         int range = to - from; 
  104.         // 如果范围大于0,即存在两个以上的元素,则继续拆分 
  105.         if (range > 0) { 
  106.             // 选定中间位 
  107.             int mid = (to + from) / 2
  108.             // 先判断两个二分的临界位 
  109.             if (input[mid] == target) { 
  110.                 return mid; 
  111.             } 
  112.             // 如果临界位不满足,则继续二分查找 
  113.             if (input[mid] > target) { 
  114.                 return binarySearch(input, target, from, mid - 1); 
  115.             } else { 
  116.                 return binarySearch(input, target, mid + 1, to); 
  117.             } 
  118.         } else { 
  119.             if (input[from] == target) { 
  120.                 return from; 
  121.             } else { 
  122.                 return null
  123.             } 
  124.         } 
  125.     } 

 


     本文转自mushiqianmeng 51CTO博客,原文链接:http://blog.51cto.com/mushiqianmeng/732739,如需转载请自行联系原作者




相关文章
|
16天前
|
Java
java实现二分查找
java实现二分查找
14 0
|
1月前
|
存储 算法 索引
【优选算法】—— 二分查找
【优选算法】—— 二分查找
|
1月前
|
算法 搜索推荐 Java
数据结构与算法(Java篇)笔记--希尔排序
数据结构与算法(Java篇)笔记--希尔排序
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 27. 移除元素 详细解读
[Java·算法·简单] LeetCode 27. 移除元素 详细解读
23 1
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 13. 罗马数字转整数 详细解读
[Java·算法·简单] LeetCode 13. 罗马数字转整数 详细解读
23 0
|
1月前
|
算法 Java
[Java·算法·简单] LeetCode 392. 判断子序列 详细解读
[Java·算法·简单] LeetCode 392. 判断子序列 详细解读
27 0
|
1月前
|
算法 Java
[Java·算法·中等] LeetCode15. 三数之和
[Java·算法·中等] LeetCode15. 三数之和
30 0
|
14天前
|
算法 测试技术 Serverless
【二分查找】【C++算法】378. 有序矩阵中第 K 小的元素
【二分查找】【C++算法】378. 有序矩阵中第 K 小的元素
|
15天前
|
算法 安全 Java
java代码 实现AES_CMAC 算法测试
该代码实现了一个AES-CMAC算法的简单测试,使用Bouncy Castle作为安全提供者。静态变量K定义了固定密钥。`Aes_Cmac`函数接受密钥和消息,返回AES-CMAC生成的MAC值。在`main`方法中,程序对给定的消息进行AES-CMAC加密,然后模拟接收ECU的加密结果并进行比较。如果两者匹配,输出&quot;验证成功&quot;,否则输出&quot;验证失败&quot;。辅助方法包括将字节转为16进制字符串和将16进制字符串转为字节。
|
25天前
|
存储 算法 JavaScript
Java入门高频考查算法逻辑基础知识3-编程篇(超详细18题1.8万字参考编程实现)
解决这类问题时,建议采取下面的步骤: 理解数学原理:确保你懂得基本的数学公式和法则,这对于制定解决方案至关重要。 优化算法:了解时间复杂度和空间复杂度,并寻找优化的机会。特别注意避免不必要的重复计算。 代码实践:多编写实践代码,并确保你的代码是高效、清晰且稳健的。 错误检查和测试:要为你的代码编写测试案例,测试标准的、边缘情况以及异常输入。 进行复杂问题简化:面对复杂的问题时,先尝试简化问题,然后逐步分析和解决。 沟通和解释:在编写代码的时候清晰地沟通你的思路,不仅要写出正确的代码,还要能向面试官解释你的
33 0