704. 二分查找
题目要求:
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ;
写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
难点:
1、注意区分target存在的区间是左闭右闭,还是左闭右开;
2、如何保证while循环过程中区间要求一直成立,即循环不变量。
3、第一次刷题,注意LeetCode的标准刷题格式,并在本地运行完成代码。
情况一,target属于[left,right]:
class Solution1 {
public:
int myFind(vector<int>& nums, int& target)//num为升序的int向量
{
int Left = 0;
int Right = nums.size() - 1;
while (Left <= Right)//target存在区间为左闭右闭,当Left=Right时,区间[left,right]也有意义,所以是<=
{
int Middle = Left + (Right - Left) / 2;
if (nums[Middle] > target)//说明target能出现在Middle的左边
{
Right = Middle - 1;//更新右边界,注意要 -1
}
else if (nums[Middle] < target)
{
Left = Middle + 1;//更新左边界,注意要 +1
}
else
{
return Middle;
}
}
return -1;//未找到target
}
};
情况二,target属于[Left,Right):
class Solution2 {
public:
int myFind(vector<int>& nums ,int& target){
int Left = 0;
int Right = nums.size();
while (Left < Right) {
int Middle = (Left + Right) / 2;
if (nums[Middle] > target) {//target位于Middle左侧且不可能为Middle,更新Right
Right = Middle;
}
else if (nums[Middle] < target) {
Left = Middle + 1;//注意,为了保证[ )的区间要求一直成立,这里要+1
}
else {
return Middle;
}
}
return -1;
}
};
while循环可以自动退出的原因:
本地完整代码:
#include<iostream>
#include<vector>
using namespace std;
//情况1,target属于[left,right]
class Solution1 {
public:
int myFind(vector<int>& nums, int& target)//num为升序的int向量
{
int Left = 0;
int Right = nums.size() - 1;
while (Left <= Right)//target存在区间为左闭右闭,当Left=Right时,区间[left,right]也有意义,所以是<=
{
int Middle = Left + (Right - Left) / 2;
if (nums[Middle] > target)//说明target能出现在Middle的左边
{
Right = Middle - 1;//更新右边界,注意要 -1
}
else if (nums[Middle] < target)
{
Left = Middle + 1;//更新左边界,注意要 +1
}
else
{
return Middle;
}
}
return -1;//未找到target
}
};
//情况2:target属于[Left,Right)
class Solution2 {
public:
int myFind(vector<int>& nums ,int& target){
int Left = 0;
int Right = nums.size();
while (Left < Right) {
int Middle = (Left + Right) / 2;
if (nums[Middle] > target) {//target位于Middle左侧且不可能为Middle,更新Right
Right = Middle;
}
else if (nums[Middle] < target) {
Left = Middle + 1;//注意,为了保证[ )的区间要求一直成立,这里要+1
}
else {
return Middle;
}
}
return -1;
}
};
int main() {
vector<int>nums = { 0,1,5,9,11,15,18,20 };
int target = 19;
Solution1 solution1;
Solution2 solution2;
cout << solution1.myFind(nums, target) << endl;
cout << solution2.myFind(nums, target) << endl;
system("pause");
return 0;
}
27. 移除元素
题目要求:
给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,
并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
解题思路:
1、暴力搜索,两层for循环。外层for循环遍历整个数组,寻找要删除的元素;内层for循环
将后面的元素索引前移。
2、快慢指针:一层for循环。for循环里,首先快指针遍历整个数组,对于不需要删除的元素
,慢指针拿到该元素并存入更新后的数组中。可以这样理解:快指针指向更新前数组的索引,
慢指针指向更新后数组的索引。
注意:数组中的元素不能删除,只能覆盖。
暴力搜索:
//暴力搜索
class Solution1 {
public:
int Violent_search(vector<int>& nums, int val) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) {
for (int j = i; j < size - 1; j++) {
nums[j] = nums[j + 1];//覆盖
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
size--; // 此时数组的大小-1
}
}
return size;
}
};
快慢指针:
//快慢指针
class Solution2 {
public:
int FastSlowPointer(vector<int>& nums, int val) {
int slowPointer = 0;
for (int fastPointer = 0; fastPointer < nums.size(); fastPointer++) {
if (nums[fastPointer] != val)
{
nums[slowPointer] = nums[fastPointer];
slowPointer++;
}
}
return slowPointer;
}
};
本地完整代码:
#include<iostream>
#include<vector>
using namespace std;
//暴力搜索
class Solution1 {
public:
int Violent_search(vector<int>& nums, int val) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) {
for (int j = i; j < size - 1; j++) {
nums[j] = nums[j + 1];//覆盖
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
size--; // 此时数组的大小-1
}
}
return size;
}
};
//快慢指针
class Solution2 {
public:
int FastSlowPointer(vector<int>& nums, int val) {
int slowPointer = 0;
for (int fastPointer = 0; fastPointer < nums.size(); fastPointer++) {
if (nums[fastPointer] != val)
{
nums[slowPointer] = nums[fastPointer];
slowPointer++;
}
}
return slowPointer;
}
};
int main() {
vector<int>nums = {0,1,3,2,1,2,3,0,1};
int val = 0;
Solution1 solution1;
Solution2 solution2;
//cout << solution1.Violent_search(nums, val) << endl;//
cout << solution2.FastSlowPointer(nums, val) << endl;
system("pause");
return 0;
}