目录
题目链接 704.二分查找(Leetcode)
目录
Leetcode 704.二分查找
题目链接 704.二分查找(Leetcode)
解题思路 知识来源
1.二分查找有两个前提,第一是 有序排列 ,第二是 无重复元素 。
2.二分法的区间定义一般分为两种,一是左闭右闭 [left, right] ,另一种是左闭右开 [left, right) 。
以数组 [2, 3, 4, 5, 8, 9] 为例,一共 6 个元素,对应下标为 0-5,当区间定义为左闭右闭时,right 初始化为 5,对应的代码为 left <= right 和 right = middle - 1 ;当区间定义为左闭右开时,right 初始化为 6 (由于元素 nums[6] 无意义,所以边界 6 为开区间) ,对应的代码为 left < right 和 right = middle 。
3.两种定义方法选择一种固定使用就好,个人建议左闭右闭,因为右边界有意义,返回结果比较清晰直观。当然,适合自己就好。
4.二分查找(折半查找)的优点:时间复杂度为logN。
5.中间值为mid=left+(right-left)/2,而不是(left+right)/2,是为了防止mid值溢出。
代码实现
int search(int* nums, int numsSize, int target){
int left=0;
int right = numsSize-1;
while(left<=right)
{
int mid = left+(right-left)/2;
if(nums[mid]==target)
{
return mid;
}
else if(nums[mid]<target)
{
left = mid+1;
}
else if(nums[mid]>target)
{
right = mid-1;
}
}
return -1;
}
总结
二分查找看起来很简单,但是还是有很多小细节需要注意。
Leetcode 27.删除元素
题目链接 27.删除元素(Leetcode)
解题思路
1.暴力解法:使用两个for循环,第一个for循环为了找到相等元素,第二个for循环为了将后面的元素向前移动覆盖掉相等的元素。
2.双指针解法:使用两个指针对一个数组进行遍历,快指针遍历数组的每一个元素,遍历的元素如果与寻找的值不相等,再赋值给慢指针。
3.时间复杂度为O(n),空间复杂度为O(1)。
代码实现
int removeElement(int* nums, int numsSize, int val){
int fast;
int slow = 0;
for(fast=0;fast<numsSize;fast++)
{
if(nums[fast]!=val)
{
nums[slow] = nums[fast];
slow++;
}
}
return slow;
}
总结
对于诸如「相同元素最多保留 k 位元素」或者「移除特定元素」的问题,更好的做法是从题目本身性质出发,利用题目给定的要求提炼出具体的「保留逻辑」,将「保留逻辑」应用到我们的遍历到的每一个位置。