题目链接: https://leetcode.cn/problems/binary-search/
题目:二分查找
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
之前敲过,此次为复习
附上之前觉得不错的视频链接
看见题目的思路:
对区间的选择,比如左闭右开,左闭右闭,//当然也有左开右闭等等,但有点麻烦就没选择写了
实现代码:
1 class Solution {
2 public:
3 int search(vector<int>& nums, int target) {
4 //左闭右闭
5 int left = 0;
6 int right = nums.size() - 1; //右闭所以right指向尾部 right]
7 //循环的时机: 左闭右闭,left 可以等于 right 所以 <=
8 while(left <= right)
9 {
10 int mid = (left + right) / 2;
11 if(target < nums[mid])
12 {
13 right = mid - 1; //右闭,所以right 要进入下一次循环
14 }
15 else if(target > nums[mid]) left = mid + 1; //左闭,mid+1
16 else return mid;
17 }
18 return -1;
19 }
20 };
注意点:
1.确定区间--left ,right的初始化--这也影响了while循环的循环条件,若为左闭右闭则left可以等于right,所以循环条件有“=”,若右开则没有。
2.循环内的指针移动,每一次进入下一次循环,left 和 right 的赋值的要符合开始的区间
比如开始为左开右闭,下一次循环,仍要满足左开右闭
若为开区间,则需要left = mid,或者right = mid,不计入下一次的循环之中。若是闭区间,left = mid+1,或者right = mid+1,因为要保持区间一致
题目:27. 移除元素
给你一个数组
nums
和一个值val
,你需要 原地 移除所有数值等于val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用
O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
一、看见题目的思路
从后面开始,覆盖前面的val。
二、代码
1.暴力解法:
这个也不是很暴力。
1 class Solution {
2 public:
3 int removeElement(vector<int>& nums, int val) {
4 //暴力解法,用遍历查找与最后一个数组元素交换,并让tail指向尾部
5 int tail = nums.size();
6 bool flag = true; //在一次循环中,没有交换元素则变成false退出循环
7 while(flag == true)
8 {
9 flag = false;
10 for(int i = 0; i < tail; i++)
11 {
12 if(nums[i] == val)
13 {
14 swap(nums[i],nums[--tail]);
15 flag = true;
16 break;
17 }
18 }
19 }
20 return tail;
21 }
22 };
2.快慢指针法
按照我个人的理解,快慢指针的指针移动的条件设定可以看成slow指向一个空数组,当fast遇到不属于val的值就录入,并且slow++
1 class Solution {
2 public:
3 int removeElement(vector<int>& nums, int val) {
4 //快慢指针法
5 int slow = 0;
6 for(int fast = 0; fast < nums.size(); fast++)
7 {
8 //实质上相当于slow指向一个空数组
9 //而fast不等于要删除的元素就进行录入
10 //同时slow加1,指向新数组的空位置
11 if(nums[fast] != val)
12 {
13 nums[slow] = nums[fast];
14 slow++;
15 }
16 }
17 return slow;
18 }
19 };
3.左右指针
左右指针的指针移动的条件设定,我也是假设left指向空数组来理解的
当left 不指向val 则移动,相当于录入新元素。
当left指向val则不移动,right赋值,改变left指向的元素来进行录入
1 class Solution {
2 public:
3 int removeElement(vector<int>& nums, int val) {
4 //左右指针法
5 //right 是否减1 影响while循环的条件是否有 =
6 //看他们相等时是否需要判断
7 int left = 0, right = nums.size() - 1;
8 while(left <= right)
9 {
10 //即设有一个新数组,left不指向val就录入,并且++
11 if(nums[left] == val)
12 {
13 nums[left] = nums[right];
14 right--;
15 }
16 else left++;
17 }
18 }
19 };
注意点:
每一次循环都只有一个指针移动