当前位置: 首页 > news >正文

网站后台登陆不了哪个网站是可以做书的

网站后台登陆不了,哪个网站是可以做书的,工业信息化部网站备案查询,wordpress 站标不显示目录 前言 一、二分查找 1.思想 2.简单二分 3.优点 4.局限性 二、模板 1.基本模板 2.简单例题(LeetCode) 4.有重复元素的二分 5.0-1问题 总结 前言 本文通过讲解简单的二分查找配合leetcode例题对二分查找本质、模板进行了基础的总结 提示&a…

目录

前言

一、二分查找

1.思想

2.简单二分

3.优点

4.局限性

二、模板

1.基本模板

2.简单例题(LeetCode)

4.有重复元素的二分

5.0-1问题

总结


前言

本文通过讲解简单的二分查找配合leetcode例题对二分查找本质、模板进行了基础的总结


提示:以下是本篇文章正文内容,下面案例可供参考

一、二分查找

1.思想

二分查找本质是折半查找思想,每一轮查找的范围是上一轮的一半,每次查找比较中间元素的值和目标值的大小。比较结论决定去哪一边作为下一轮的查找范围,循环直到查找范围为空。

2.简单二分

简单二分指的是数组不包含重复的元素,重点关注每次判边的逻辑。

3.优点

速度快 O(logn)且不需要额外的空间

4.局限性

  • 有序:需要保证每次折半都有意义
  • 数组:数组寻址的复杂度是 O (1)。如果是用链表存储一串数,二分查找是无意义的。链表的寻址是 O (n)。

二、模板

1.基本模板

二分查找的模板很多样,开闭的条件不同,判断的条件也不同

最本质的问题是当前判断结束后,下一次要取左半边还是右半边缩小区间的条件是什么?判断的条件是什么 

注意:

  1. left<=right:实际进入循环时,left和right只向的元素不会进行if条件判断。比如left=right时,加此等号,才会对二者所指元素进行判断。否则不会。
  2. mid =(left+right)>>>1:因为java会把最高位看成符号位,如果两个数过大,可能会导致数据溢出问题。我们需要通过无符号右移运算符来避免这种问题。还有一种写法是mid=left+(right-left)/2
  3. 更新left和right,避免死循环
public static int binarySerach(int[] a,int target){int left=0;int right=a.length-1;while(left<=right){int mid=(left+right)>>>1;if(target<a[mid]){//目标数在左边right=mid-1;}else if(a[mid]<target){//目标书在右边left=mid+1;}else{return mid;}}return -1;
}

2.简单例题(LeetCode)

1.704. 二分查找(基本简单)

class Solution {public int search(int[] nums, int target) {int left=0;int right=nums.length-1;while(left<=right){int mid=(left+right)>>>1;if(nums[mid]<target){left=mid+1;}else if(nums[mid]>target){right=mid-1;}else{return mid;}}return -1;}
}

2.744.寻找比目标字母大的最小字母

class Solution {public char nextGreatestLetter(char[] letters, char target) {int left=0;int right=letters.length-1;while(left<=right){int mid=(left+right)>>>1;if(letters[mid]<=target){left=mid+1;}else{right=mid-1;}}return left<letters.length?letters[left]:letters[0];}
}

3.74. 搜索二维矩阵

class Solution {public boolean searchMatrix(int[][] matrix, int target) {int left=0;//使用m*n将二维转为一维int m=matrix[0].length;int n=matrix.length;int right=m*n-1;while(left<=right){int mid=(left+right)>>>1;int x=matrix[mid/m][mid%m];//把mid元素转换回原二维矩阵的位置if(x==target){return true;}else if(x>target){right=mid-1;}else{left=mid+1;}}return false;}
}

4.162. 寻找峰值

此题究其本质依然是二分查找,我们需要根据题目重要条件进行理解

“你可以假设 nums[-1] = nums[n] = -∞ 。”

以下做法需要注意边界情况的判断

class Solution {public int findPeakElement(int[] nums) {int n = nums.length;if (n == 1) {return 0;}int left = 0, right = n - 1;while (left <= right) {int mid = left + (right - left) / 2;// 边界情况判断:数组第一个元素是峰值(只有它自己,或者比下一个大)if (mid == 0) {if (nums[mid] > nums[mid + 1]) {return mid;}}// 边界情况判断:数组最后一个元素是峰值(只有它自己,或者比前一个大)else if (mid == n - 1) {if (nums[mid] > nums[mid - 1]) {return mid;}}// 中间位置是峰值(比左右都大)else if (nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]) {return mid;}// 判断峰值在左侧还是右侧if (nums[mid] < nums[mid + 1]) {// 右侧有上升趋势,峰值在右侧left = mid + 1;} else if (nums[mid] < nums[mid - 1]) {// 左侧有上升趋势,峰值在左侧right = mid - 1;}}// 理论上不会走到这里,因为题目保证有解return -1;
}}

题解中的做法是无需单独判断边界情况的,也没有主动对mid元素与左右两元素进行比较

因为左右边界都是负无穷,找到往递增的一边方向找就一定能找到峰值(图中白圈内区域)。这就代表着 只要数组中存在一个元素比相邻元素大,那么沿着它一定可以找到一个峰值。

特点:一分为二后,一侧是有序数组,另一侧是循环数组。

根据这个特点,先判断有序数组、循环数组分别在哪一侧,再判断 target 在有序数组 还是 循环数组中

判断方法是让 target 和有序数组的首尾做比较,看是否在有序数组中。

1. 3. 搜索旋转排序数组

class Solution {public int search(int[] nums, int target) {int left=0;int right=nums.length-1;while(left<=right){int mid=(left+right)>>>1;if(nums[mid]==target){return mid;}//左半部分有序if(nums[left]<=nums[mid]){//目标值在左半部分区间内if(nums[left]<=target && target<nums[mid]){right=mid-1;}else{left=mid+1;//缩小范围到右半部分区间}}// 右半部分是有序的else {// 目标值在右半部分有序区间内if (nums[mid] < target && target <= nums[right]) {left = mid + 1;} else {right = mid - 1;//缩小范围到左半部分区间}}}return -1;}}

2.153. 寻找旋转排序数组中的最小值

不多说了,都在注解里:

最主要的还是需要判断目标值到底是在mid的左边还是右边,才能进行下一步二分。而判断依据就是根据两端递增区间的特性将nums[mid]和nums[right]进行比较。这也就是开篇说的判断取左半段还是右半段最重要的条件。

class Solution {public int findMin(int[] nums) {int left=0;int right=nums.length-1;while(left<=right){int mid=(left+right)>>>1;//首先由题可知,数组一定被分为了左右两个递增区间(或者没分,也就是0次旋转),且第一段所有元素大于第二段所有元素//需要比较nums[mid]和nums[right]的关系。//如果<=,意味着nums[mid]一定处于第二个递增区间,最小值要么是该元素,要么就在该元素左侧//如果>,意味着nums[mid]处于第一个递增区间。最小值一定在该元素右侧if(nums[mid]>nums[right]){//mid处于左半段left=mid+1;}else{//mid处于右半段if(mid==0||nums[mid]<=nums[mid-1]){//mid就是最小值,注意mid=0时索引越界问题return nums[mid];}else{//mid处于右半段,但最小值在mid的左边right=mid-1;}}}return -1;}
}

4.有重复元素的二分

通常要求找出第一个目标元素或是最后一个目标元素

存在重复元素的二分查找,无非就是多加了一个判断,判断是否为第一个/最后一个。

以查询第一个目标元素为例,判断条件就是看mid-1是否等于target,如果不是,那么mid就是我要

找的数了。这依然是二分关键。

public class BinarySearch {public static int binarySearch(int[] nums, int target) {int left = 0;int right = nums.length - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] < target) {left = mid + 1;} else if (nums[mid] > target) {right = mid - 1;} else {// 当找到目标值时,判断是否是第一个出现的位置if (mid == 0 || nums[mid - 1] != target) {//是第一个元素,注意索引越界问题。return mid;} else {right = mid - 1;}
//以下为找最后一个目标元素的判断条件
//if (mid == nums.length-1 || nums[mid+1]!=target){
//}else{
// left=mid+1;}}}return -1;}public static void main(String[] args) {int[] nums = {1, 3, 8, 8, 8, 9};int target = 8;int result = binarySearch(nums, target);System.out.println("第一个目标值 " + target + " 的索引是: " + result);}
}

5.0-1问题

点到为止,下期再见。


总结

本文对二分查找进行简单讲解,还有比较常见的二分查找应用“0-1问题”留着下期讲解。

二分的模板多种多样,但究其本质最重要的还是如何判断下一次二分的区间,取左边还是取右边。这个就是需要根据不同题目思考的点了

http://www.dtcms.com/a/433471.html

相关文章:

  • 深圳深圳做网站长沙做网站哪里好
  • 公明做企业网站安徽安庆邮编
  • 网站建设的定位是什么意思wordpress手机号登陆
  • 青岛网站公司厚街商城网站建设
  • 深圳营销型网站建设电话漳州网站建设 林
  • 站长之家下载湖州市南浔区建设局网站
  • 深圳极速网站建设报价google play商店
  • 哪里可以免费建设网站品牌建设计划书
  • 蒙古网站群建设餐饮网站建设服务器
  • 韩国设计app网站有哪些做网站行情
  • 5050众筹网站开发常德德山经开区建设局网站
  • 德化住房和城乡建设网站鄂州官方网站
  • 校园加盟网站建设超低价的锦州网站建设
  • 网泰网站建设wordpress打开邮箱
  • 潍坊网站开发公司班级网站首页怎么做
  • 做暧暧视频免费网站章丘网站优化
  • 专做化妆品的网站港南网站建设
  • 古典水墨网站遇到钓鱼网站怎么做
  • 深圳专业专业网站设计公司一般网站服务器
  • vi设计公司 焕识湖南关键词优化推荐
  • 网站建设word文档嵌入式软件开发工程师培训
  • 济南网站制作培训班成都市网站建
  • 网站设计属于什么经营范围多用户商城系统的效果
  • 郑州市建网站不得不知道网站
  • Tailwind预定义样式类(框架内置)(文本样式类、布局与间距类(弹性布局、网格布局)、颜色类、响应式设计类)任意值(Arbitrary Values)功能
  • 江西网站建设网络公司莱芜一中贴吧
  • 阿里巴巴网站备案网络公司是什么公司
  • 建设银行深圳天健世纪支行网站如何做宣传推广营销
  • 优化推广网站淄博seo在线网站推广
  • 东莞网站建设企业专门做dnf补丁的网站