二分查找的思想
二分查找的基本思想是将有序数组分成两部分,取a [n/2]与x做比较,如果x=a [n/2],则找到x,算法中止;如果x<a [n/2],则要在数组a的左半部分继续搜索x,如果x>a [n/2],则要在数组a的右半部搜索x。
算法复杂度:O(log2n)。
使用条件:1.数组是有序的
2.数组元素无重复
leetcode704:二分查找
题目链接:力扣
题目大意:
给定一个升序整型数组 nums和目标值target, 写一个搜索 nums 中的 target的函数,如果目标值存在返回下标,否则返回 -1。
分析:由于数组是升序数组,因此满足二分查找的使用条件。使用查找是需要注意我们的查找范围是什么区间,不同区间存在不同的细节处理。
1.左闭右闭区间
class Solution { public: int search(vector<int>& nums, int target) { int l = 0; int r = nums.size()-1; int mid = 0; while(l<=r) { mid =l+(r-l)/2; if(nums[mid]==target) { return mid; } else if(nums[mid] < target) { l = mid+1; } else if(nums[mid] > target) { r = mid - 1; } } return -1; } };
2. 左闭右开区间
class Solution { public: int search(vector<int>& nums, int target) { int l = 0; int r = nums.size(); int mid = 0; while(l < r) { mid = l+(r-l)/2; if(nums[mid] == target) { return mid; } else if(nums[mid] < target) { l=mid+1; } else if(nums[mid] > target) { r = mid; } } return -1; } };
两者区别:1.right的初始化不同前者。
2.循环条件不同
3.right指针的更新方式不同
快慢指针的思想:
就是使用两个移动速度不同的指针在数组或链表等序列结构上移动。
leetcode27移除元素
题目链接:力扣
题目大意:给你一个数组
nums
和一个值val
,你需要原地移除所有数值等于val
的元素,并返回移除后数组的新长度。1.暴力解法:
class Solution { public: int removeElement(vector<int>& nums, int val) { int size = nums.size()-1; for(int i = 0; i <=size; i++) { if(nums[i] == val) { for(int j = i+1; j <= size;i++) { nums[j-1] =nums[j]; } i--; size--; } } return size; } };
算法时间复杂度:o(n^2)
2.快慢指针
使用快慢指针只需遍历一次,慢指针用于更新数组。
class Solution { public: int removeElement(vector<int>& nums, int val) { int size = nums.size()-1; int slow = 0; int fast = 0; while(fast <= size) { if(nums[fast] != val) { nums[slow] = nums[fast]; fast++; slow++; } else fast++; } return slow; } };
算法时间复杂度:o(n)