前言
一个本硕双非的小菜鸡,备战24年秋招,计划刷完卡子哥的刷题计划,加油! 推荐一手卡子哥的刷题网站,感谢卡子哥。代码随想录
一、977. 有序数组的平方
力扣977. 有序数组的平方 Note:模拟就完了,非常简单(有高级做法,放在后面写)
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
for (int i = 0; i < nums.size(); i++) {
nums[i] *= nums[i];
}
sort(nums.begin(), nums.end());
return nums;
}
};
头尾指针法,一个头一个尾,比较哪个大,并新建一个数组存储结果
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int k = nums.size() - 1;
vector<int> result(nums.size(), 0);
for (int i = 0, j = nums.size() - 1; i <= j;) {
if (nums[i] * nums[i] < nums[j] * nums[j]) {
result[k--] = nums[j] * nums[j];
j--;
} else {
result[k--] = nums[i] * nums[i];
i++;
}
}
return result;
}
};
二、88. 合并两个有序数组
Note:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
while (left <= right) {
int middle = left + ((right - left) / 2);
if (nums[middle] > target) {
right = middle - 1;
} else if (nums[middle] < target) {
left = middle + 1;
} else {
return middle;
}
}
return left;
}
};
三、34. 在排序数组中查找元素的第一个和最后一个位置
Time / Space:时间16 ms,内存13.2 MB Note:官方题解比较通俗易懂,说白了就是把二分查找当作一个函数来调用。
class Solution {
public:
int binarySearch(vector<int>& nums, int target, bool lower) {
int left = 0;
int right = nums.size() - 1;
int ans = nums.size();
while(left <= right) {
int middle = left + ((right - left) / 2);
if (nums[middle] > target || (lower && nums[middle] >= target)) {
right = middle - 1;
ans = middle;
} else {
left = middle + 1;
}
}
return ans;
}
vector<int> searchRange(vector<int>& nums, int target) {
int leftIndex = binarySearch(nums, target, true);
int rightIndex = binarySearch(nums, target, false) - 1;
if(leftIndex <= rightIndex && rightIndex < nums.size() && nums[leftIndex] == target && nums[rightIndex] == target) {
return vector<int>{leftIndex, rightIndex};
}
return vector<int>{-1, -1};
}
};
四、367. 有效的完全平方数
Time / Space:时间4 ms击败25.44%,内存5.8 MB击败31.10% Note:两个middle相乘会超过int,记着用long
class Solution {
public:
bool isPerfectSquare(int num) {
int leftIndex = 0;
int rightIndex = num;
while (leftIndex <= rightIndex) {
long middle = leftIndex + ((rightIndex - leftIndex) / 2);
if (middle * middle > num) {
rightIndex = middle - 1;
} else if (middle * middle < num) {
leftIndex = middle + 1;
} else {
return true;
}
}
return false;
}
};
总结
写二分法经常写乱,主要是因为对区间的定义没有想清楚,区间的定义就是不变量。要在二分查找的过程中,保持不变量,就是在while寻找中每一次边界的处理都要坚持根据区间的定义来操作,这就是循环不变量规则。 写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。