目录
1、数组理论基础
2、二分查找
2.1 区间左闭右闭写法
2.2 区间左闭右开写法
3、移除元素
3.1 暴力解法
3.2 双指针(快慢指针)法
参考以前的博客:http://t.csdn.cn/HAVSF
力扣https://leetcode.cn/problems/binary-search/
【题目】给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
【参考代码】
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){right = mid-1;}else if(nums[mid]
首先关于这个二分查找法,主要有两个易错点,一个是while循环条件里面的符号究竟是小于等于还是小于。另一个是if—else if—else里面的判断体究竟需不需要进行加一减一的操作。
要解决这个问题还是从问题本身出发,那就是没有搞清楚区间的定义,而定义过的区间就是固定的,即“不变量”。每一次循环里面的处理都需要根据区间来选择,这也是为什么有时候有些题加一减一似乎对其没什么影响,但有时候又必须加一或者减一。
下面给出二分法写法的两个版本:
int search(int* nums, int numsSize, int target){int left = 0;int right = numsSize - 1;while(left<=right){int mid = left+(right-left)/2;//int mid = (left+right)/2;//int mid = left+(right-left)>>1;if(nums[mid]>target){right = mid-1;}else if(nums[mid]
在这种情况下,target是定义在[left,right]上的,此时left=right是有意义的,注意这里跟数学里面的区间定义不同,因为有意义,所以此时while(left<=right),如果你少写=,会有值被你漏算。除此之外,你还需要注意一下if判断体里面是否需要加一或减一,如果nums[mid]>target,说明当前的nums[mid]一定不是target,所以更新后的搜索右下标范围为mid-1。
int search(int* nums, int numsSize, int target){int left = 0;int right = numsSize;while(left
target){right = mid;}else if(nums[mid] 在这种情况下,target是定义在[left,right)上的,此时left=right是没有意义的,因为没有意义,所以此时while(left
target,说明当前的nums[mid]一定不是target,而右区间本就是开区间,所以更新后的搜索右下标范围为mid。但nums[mid]
【相关题目训练】
1.力扣https://leetcode.cn/problems/search-insert-position/
2.力扣https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/3.力扣https://leetcode.cn/problems/sqrtx/4.力扣https://leetcode.cn/problems/valid-perfect-square/
力扣https://leetcode.cn/problems/remove-element/
【题目】给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并原地修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
【思路】要知道数组的元素在内存地址中是连续的,不能单独删除数组中的某个元素,只能覆盖。
以下给出两个方法:
//两个for循环,一个for遍历整个数组元素,另一个更新数组元素 int removeElement(int* nums, int numsSize, int val){for(int i=0;i
在本代码中:
- 时间复杂度:
- 空间复杂度:
通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。
定义快慢指针:
- 寻找新数组的元素 ,新数组就是不含有目标元素的数组
- 指向更新后新数组下标的位置
int removeElement(int* nums, int numsSize, int val){int slow = 0;for(int fast =0;fast
在本代码中:
- 时间复杂度:
- 空间复杂度:
【本题小结】显然法二明显优于法一,双指针法在数组和链表的操作中是很常见的,很多数组链表OJ题都可以使用双指针法解决。
【相关题目训练】
力扣https://leetcode.cn/problems/remove-duplicates-from-sorted-array/
力扣https://leetcode.cn/problems/move-zeroes/
力扣https://leetcode.cn/problems/backspace-string-compare/
力扣https://leetcode.cn/problems/squares-of-a-sorted-array/