目录
一、记录打卡
记录第一次写博客,同时也是记录在代码随想录训练营刷题的第一天,希望激励自己坚持刷下去以及每日打卡。
今天的三道题用到了二分和双指针。
二、704. 二分查找
该题是一个二分模板题,需要注意的是
1、其中防溢出的解决办法:将代码int mid=(right+left)/2改为(right-left)/2+left,进而防止其运行途中超过int型最大值。
2、nums[i]大于target与小于target时left或者right相对应的位置
代码如下:
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0;
int right=nums.size()-1;
while(left<=right){
int mid=(right+left)>>1; //改用int mid=left+((right-left)/2),可作为防溢出(防止left+right过大)使用
if(nums[mid]==target)
return mid;
else if(nums[mid]<target) //此时target存在于(mid+1,right)间
left=mid+1;
else
right=mid-1;
}
return -1;
}
};
附一张通过结果:
三、27. 移除元素
题目要求:移除数组中值为val的元素
思路一:暴力求解
附上一张卡哥的解法:其实就是将数组nums中值为val的元素在原数组中移除,通过多加的一层j循环将除去元素后的集体向前移动一位。(关键在于多设立的一层j循环)
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
size--; // 此时数组的大小-1
}
}
return size;
}
};
思路二:双指针
先附上一张自己的做法(不够优化)
具体思路:定义两个指针fast与slow,fast用于遍历数组nums中所有元素,slow用于存放nums中值不为val的目标元素,最终返回slow即为所得。
代码如下:
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow=0,fast=0;
while(fast<nums.size())
{
if(nums[fast]!=val)
{
nums[slow]=nums[fast];
slow++;
}
fast++;
}
return slow;
}
};
四、 977. 有序数组的平方
思路一:暴力+排序
先将数组里每个元素平方,再排序。
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for (int i = 0; i < nums.size(); i++) {
nums[i] = nums[i] * nums[i];
}
sort(nums.begin(), nums.end());
return nums;
}
};
思路二:双指针
这里为什么可以使用双指针呢?
因为平方的最大值一定在两端点取得 -- 两端点元素要么正的多,要么负的多,平方之后,值就会是最大 -- 通过双指针,遍历当前两端点,将较大的平方值移动到结果数组ans末尾即可。(这里需要注意的就是指针是如何移动的)
代码如下:
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int len = nums.size() - 1;
vector<int> ans(nums.size()); //copy一个与nums同样长度的数组ans
int left = 0;
int right = nums.size() - 1;
while (left <= right) { //从后往前(从大到小)存放元素:大的平方值移到结果数组ans末尾
if (nums[right] * nums[right] > nums[left] * nums[left]) {
ans[len--] = nums[right] * nums[right];
right--;
}
else {
ans[len--] = nums[left] * nums[left];
left++;
}
}
return ans;
}
};
五、小结
第一天打卡到此也就结束了,我是算法小白,但也希望在后来的日子里不断进步。