代码随想录算法训练营第1天|704. 二分查找、27. 移除元素
704. 二分查找
提交代码(二分法)
class Solution {
public:
int search(vector<int>& nums, int target) {
int len = nums.size();
int left = 0;
int right = len - 1;
int mid = left + (right - left) / 2;
while(left <= right)
{
if(nums[mid] == target)
return mid;
else if(nums[mid] < target)
left = mid + 1;
else
right = mid - 1;
mid = left + (right - left) / 2;
}
return -1;
}
};
解答代码(二分法)
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while(left <= right){
int mid = (right - left) / 2 + left;
int num = nums[mid];
if (num == target) {
return mid;
} else if (num > target) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return -1;
}
};
27. 移除元素
提交代码(双指针)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int len = nums.size();
int left = 0;
int right = len - 1;
while(left < right + 1)
{
if(nums[left] == val)
{
nums[left] = nums[right];
right--;
}
else
left++;
}
return left;
}
};
解答代码(方法1-双指针)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size();
int left = 0;
for (int right = 0; right < n; right++) {
if (nums[right] != val) {
nums[left] = nums[right];
left++;
}
}
return left;
}
};
解答代码(方法2-优化的双指针)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int left = 0, right = nums.size();
while (left < right) {
if (nums[left] == val) {
nums[left] = nums[right - 1];
right--;
} else {
left++;
}
}
return left;
}
};
解答代码(方法3-优化的双指针)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int j = nums.size() - 1;
for (int i = 0; i <= j; i++) {
if (nums[i] == val) {
swap(nums[i--], nums[j--]);
}
}
return j + 1;
}
};
总结
日期: 2023 年 3 月 15 日
学习时长: 1 h 0 m
难度:
★
\bigstar
★
★
\bigstar
★
★
\bigstar
★
累计完成题目数量: 2
距离目标还有数量: 298
小结:
- 关于27题的方法1,解答中说我们需要遍历该序列至多两次,为什么,我咋感觉都是一次?
解答: - 循环条件left < right + 1感觉很奇怪,很少有这种循环条件。这是因为初始定义right是长度减一,而不是长度,因为是长度减一,所以当数组长度为1的时候,根本进不去循环,那么当这个长度为1的数组刚好是目标元素的时候,就会出问题,因此定义循环条件是这样的。看了解答之后,发现初始定义为长度就可以了。