首页 > 编程语言 >代码随想录算法训练营第一天|704.二分查找、27.移除元素

代码随想录算法训练营第一天|704.二分查找、27.移除元素

时间:2023-02-01 13:44:06浏览次数:51  
标签:27 target nums int 随想录 middle right 移除 left

LeetCode 704.二分查找(C++)

题目链接:704.二分查找 力扣leetCode

二分查找 算法思路:

二分查找需要保证数组为有序数组同时无重复元素,否组无法通过二分查找进行判断(结果无法唯一)

 二分查找通过不断收缩数组,趋近中间值进行,由于有序,可以通过中间值与目标的比较实现

①左闭右闭区间

 1 class Solution {
 2 public:
 3     int search(vector<int>& nums, int target) {
 4         int left =0;
 5         int right =nums.size()-1;//right为最右边,target定义在左闭右闭区间
 6         while (left <=right){//left==right是依然有效
 7             int middle=left+((right-left)/2);//防止溢出,left right middle均为下标值
 8             if(nums[middle]>target){  
 9                 right=middle-1;        //在左区间,[left,middle-1]
10             }
11             else if(nums[middle]<target){
12                 left=middle+1;       //target在右区间,所以[middle+_1,right]
13             }
14             else{
15                 return middle;   //target==mums[middle],输出下标值
16             }
17         }
18         return-1;//未找到目标值 
19     }
20 };

左闭右闭区间中,left==right 是有意义的,因此在进行循环的边界判断中需要left<=right

▲middle=left+(right-left)/2等同于(left+right)/2,可以防止溢出。原因:当left和right足够大时,left+right后可能导致结果超出范围,如果使用left+(right-left)/2则可以保证middle始终在left和right之间。right-left必定小于数组范围。

②左闭右开区间

左闭右开区间中,left==right是没有意义的,因此判断中用left<right

 1 // 版本二
 2 class Solution {
 3 public:
 4     int search(vector<int>& nums, int target) {
 5         int left = 0;
 6         int right = nums.size(); // 定义target在左闭右开的区间里,即:[left, right)
 7         while (left < right) { // 因为left == right的时候,在[left, right)是无效的空间,所以使用 <
 8             int middle = left + ((right - left) >> 1);
 9             if (nums[middle] > target) {
10                 right = middle; // target 在左区间,在[left, middle)中
11             } else if (nums[middle] < target) {
12                 left = middle + 1; // target 在右区间,在[middle + 1, right)中
13             } else { // nums[middle] == target
14                 return middle; // 数组中找到目标值,直接返回下标
15             }
16         }
17         // 未找到目标值
18         return -1;
19     }
20 };

▲left一定是middle+1,因为middle已经确定≠target,所以要加一进行区间判断。

由于是左闭右开,middle<target即可保证判断区间时不会含上middle,所以right=middle即可,左闭右闭区间需要right=middle-1

LeetCode 27. 移除元素(C++)

题目链接:27.移除元素LeetCode

移除元素算法思路

 

总结

 leetCode中的时间不用在意,只要保证O(n)最小即可。时间复杂度排序:O(log)<O(n)<O(nlog)<O(n²)。

leetCode是在外部进行main函数调用,因此输出结果时一定是return n; 可以先写出来main中的输出结果,将其return即可。

标签:27,target,nums,int,随想录,middle,right,移除,left
From: https://www.cnblogs.com/bailichangchuan/p/17081041.html

相关文章