LC Binary-Search summary

本文精选了多个经典的二分查找算法题目,包括旋转有序数组查找、求解峰值元素等,深入探讨了不同场景下的二分查找应用技巧及实现细节。

相关思路:有些问题用BS的思路很明显,有些就不是那么清楚,比如有些min-max问题,求满足一定条件的最大值之类的


相关的题目有:

1、Rotated Sorted Array相关问题(idea就是总是有一半的数组是sorted),

2、BS下标控制(偏向左边,右边)与while循环条件(lo<hi还是lo<=hi还是其它)判断控制,以及标准二分返回值的理解(如果没有找到,并且返回值不是0,那返回值就是要插入的位置)

3、一些隐含Binary Search解法的题



贴几个题


33. Search in Rotated Sorted Array

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

/*
 * one half is always sorted
 */
public class Solution {
    public int search(int[] nums, int target) {
    	if(nums.length == 0)	return -1;
        int lo = 0, hi = nums.length-1;
        while(lo < hi) {
        	int mid = lo + (hi-lo)/2;
        	if(nums[mid] == target)	return mid;
        	
        	if(nums[mid] < nums[hi]) {
        		if(target > nums[mid] && target <= nums[hi])
        			lo = mid + 1;
        		else
        			hi = mid - 1;
        	} else {
        		if(target >= nums[lo] && target < nums[mid])
        			hi = mid - 1;
        			
        		else
        			lo = mid + 1;
        	}
        }
        
        return nums[lo] == target ? lo : -1;
    }
}

34. Search for a Range

Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

/*
 * bias to left & right
 */
public class Solution {
    public int[] searchRange(int[] nums, int target) {
    	if(nums.length == 0)	return new int[]{-1,-1};
        int lo=0, hi=nums.length-1;
        
        while(lo < hi) {
        	int mid = lo + (hi-lo)/2;
        	if(nums[mid] > target) 
        		hi = mid-1;
        	else if(nums[mid] < target)
        		lo = mid+1;
        	else
        		hi = mid;
        }
        int left = lo;
        if(nums[lo] != target)	return new int[]{-1,-1};
        
        lo=0; hi=nums.length-1;
        while(lo < hi) {
        	int mid = lo + (hi-lo+1)/2;
        	if(nums[mid] > target) 
        		hi = mid-1;
        	else if(nums[mid] < target)
        		lo = mid+1;
        	else
        		lo = mid;
        }
        int right = lo;
        
        return new int[]{left, right};
    }
}



162. Find Peak Element

A peak element is an element that is greater than its neighbors.

Given an input array where num[i] ≠ num[i+1], find a peak element and return its index.

The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.

You may imagine that num[-1] = num[n] = -∞.

For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2.

/*
 * 可以转换为求数组中的最大值
 * 因为只要求出一个合理的peak,所以只要在一个子数组里面求出max也可以
 */
public class Solution {
    public int findPeakElement(int[] nums) {
        int lo = 0, hi = nums.length-1;
        while(lo < hi) {
        	int mid1 = lo + (hi - lo) / 2;
        	int mid2 = mid1 + 1;
        	
        	// num[i] ≠ num[i+1]
        	if(nums[mid2] > nums[mid1]) // 只要找mid2后面的子数组的最大值
        		lo = mid2;
        	else
        		hi = mid1;
        }
        
        return lo;
    }
}


209. Minimum Size Subarray Sum

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.

For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.


这个题用2 pointer当然是最优的,但是也隐含得可以用二分

因为要求最小值,又要满足一定条件:sum>s,二分范围就是0到数组的长度


74. Search a 2D Matrix && 240. Search a 2D Matrix II

240可以做到O(m+n),最开始想的是在第一行,第一列二分减小后续搜索的范围

/*
 * 1. BS 第一行,第一列narrow down范围
 * 2. Heap:把第一行放到Heap里面,然后不断往下,这个好像是Brute force
 */
public class BS {
    public boolean searchMatrix(int[][] matrix, int target) {
    	if(matrix.length == 0 || matrix[0].length == 0)
    		return false;
    	
        int n = Arrays.binarySearch(matrix[0], target);
        if(n > 0)	return true;
        if(n == -1)	return false;
        
        int[] a = new int[matrix.length];
        for(int i=0; i<a.length; i++)
        	a[i] = matrix[i][0];
        int m = Arrays.binarySearch(a, target);
        if(m >= 0)	return true;
        if(m == -1)	return false;
        
        n = -(n+1);
        m = -(m+1);
        System.out.println(n);
        System.out.println(m);
        for(int i=0; i<m; i++) {
        	if(matrix[i][n-1] > target) {
        		if(Arrays.binarySearch(matrix[i], 0, n, target) > 0)
        			return true;
        	} else if(matrix[i][n-1] == target) {
        		return true;
        	}
        }
        
        return false;
    }
}

后发现更好的解法

/*
 * 有一个O(m+n)的方法
 * 从右上角开始, 比较target 和 matrix[i][j]的值. 如果小于target, 则该行不可能有此数,  所以i++; 
 * 如果大于target, 则该列不可能有此数, 所以j--. 
 * 遇到边界则表明该矩阵不含target
 */
public class Solution {
    public boolean searchMatrix(int[][] matrix, int target) {
    	if(matrix.length == 0 || matrix[0].length == 0)
    		return false;
    	
    	int row = 0, col = matrix[0].length-1;
    	while(true) {
    		if(matrix[row][col] == target)
    			return true;
    		else if(matrix[row][col] < target)
    			row ++;
    		else
    			col --;
    		
    		if(row == matrix.length || col == -1)
    			return false;
    	}
    }
}


230. Kth Smallest Element in a BST

LC上把树也放到二分tag里面了,树本身就是一种二分结构嘛

/*
 * 树相关的问题也放到了Binary Search里面
 * 1. 求出左子树的节点数,决策是往左走还是往右走
 * 2. 上面其实可以在求左子树节点数的时候就拿kth求出来了,即inorder tree 遍历
 */
public class Solution {
	int ret = -1;
	int cnt = 0;
    public int kthSmallest(TreeNode root, int k) {
        cnt = k;
        inorder(root);
        return ret;
    }
	private void inorder(TreeNode root) {
		if(root == null)	return;
		inorder(root.left);
		cnt--;
		if(cnt == 0) {
			ret = root.val;
			return;
		}
		inorder(root.right);
	}
}




内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值