二分搜索及其变形应用
来源:互联网 发布:c语言多线程实例 编辑:程序博客网 时间:2024/05/28 15:30
二分搜索(折半查找)是应用很广泛的一种算法,当出现有序序列时,我们可以立马想到能否可以用二分法,其写法也较为固定。我们可以把二分法视为分治的应用。但是如果不注意其变换条件也是很容易写错。下边给出了二分查找的非递归和递归写法,只要注意其边界判断和变换,代码很简单:
二分法的递归和非递归写法
package com.blog.binarysearch;/** * @Description: 二分法(二分搜索 折半查找) 有序序列的搜索 时间复杂度为O(logn) * @Author: Jingzeng Wang * @Date: Created in 15:56 2017/7/23. */public class BinarySearchDemo { public static void main(String[] args) { int[] nums = {1, 2, 3, 5, 7, 9, 11, 13}; System.out.println(binarySearch(nums, 11)); System.out.println(binarySearchRecursive(nums, 11, 0, nums.length - 1)); } /** * 二分 非递归版本 * <p> * right = num.length left < right right = mid; 另一种写法 * * @param nums 已排序数组 * @param keyNum 待查找数字 * @return 返回查找的索引位置 没有则返回-1 */ public static int binarySearch(int[] nums, int keyNum) { int left = 0; int right = nums.length - 1; while (left <= right) { //int mid = start + (end - start) / 2; //直接平均可能溢出,可以用此算法 int mid = (left + right) / 2; if (nums[mid] < keyNum) { left = mid + 1; } else if (nums[mid] > keyNum) { right = mid - 1; } else { return mid; } } return -1; } /** * 二分搜索的递归写法 * * @param nums * @param value * @param left * @param right * @return */ public static int binarySearchRecursive(int[] nums, int value, int left, int right) { if (left > right) return -1; int mid = left + (right - left) / 2; if (nums[mid] < value) return binarySearchRecursive(nums, value, mid + 1, right); else if (nums[mid] > value) return binarySearchRecursive(nums, value, left, mid - 1); else return mid; }}
二分法的变形应用
二分法的变形很多种,但是只要掌握了二分的核心思想,将转移条件写正确,基本就可以解决这些问题。比如一个有序序列中药查找的那个数出现很多次,求第一个出现的位置,求它最后出现的位置,求第一个小于某个数的数的位置,求第一个大于某个数的位置等等,只要出现有序序列,我们就可以思考此问题可否用二分法解决。下边给出一个题:统计一个数字在排序数组中出现的次数。
// hash表可以 遍历也可以 但是排序数组肯定有用 二分啊// 二分的变形:找正好大于k的那个数的位置 与 正好小于k 的位置 然后相减 时间复杂度为 O(logn)// 定位k第一次出现的位置 和 最后一次出现的位置public class Solution { public int GetNumberOfK(int [] array , int k) { if (array == null || array.length <= 0) { return 0; } int left = 0; int right = array.length - 1; int mid1 = (left + right) >> 1; // 找第一个k while (left <= right) { if (array[mid1] >= k) { right = mid1 - 1; } else { left = mid1 + 1; // < left 是始终指向小于k的 最后也是+1获得第一个k } mid1 = (left + right) >> 1; } mid1 = left; left = 0; right = array.length - 1; int mid2 = (left + right) >> 1; //找最后一个k while (left <= right) { if (array[mid2] > k) { right = mid2 - 1; // 大于k的 获得最后一个k } else { left = mid2 + 1; } mid2 = (left + right) >> 1; } mid2 = right; return mid2 - mid1 + 1; }}
阅读全文
0 0
- 二分搜索及其变形应用
- 二分搜索及其变形讨论
- 二分搜索及其变形--java实现
- 二分查找及其变形
- 二分查找及其变形算法
- 二分查找及其变形总结
- 二分查找及其变形整理
- 二分搜索及其扩展
- 二分搜索及其扩展
- 二分查找的变形应用
- 二分查找及其应用
- 二分搜索的应用
- 二分搜索应用
- 二分搜索应用二
- 二分查找法及其应用
- 二分查找实现及其应用
- 二分查找及其变化应用
- 二分搜索的巧妙应用
- 官方jdbc方式访问hive服务器
- 柏林曼の蓝色的泪
- LightOJ-1001-Opposite Task
- RGB和HSV的关系
- HTML之JavaScript自学笔记(4)
- 二分搜索及其变形应用
- (三)泛型学习笔记—通配符
- 【网络流24题】数字梯形(二分图+最大费用流)
- 算法符号Θ, O, Ω
- Noip2016 Day1 T1 玩具谜题(字符串模拟)
- 【shell编程学习】for 和 while循环
- Java网页数据采集器[下篇-数据查询]
- 算是面试题, 写的不算工整.....
- 线程基础:多任务处理——Fork/Join框架(要点1)