704.二分查找
题目链接:704.二分查找
暴力解法:遍历数组,如果存在nums[i] == target,则返回i;否则返回 -1。
class Solution {
public:
int search(vector<int>& nums, int target) {
for(int i = 0;i < nums.size() ;i++){
if(nums[i] == target){
return i;
}
}
return -1;
}
};
二分法:以middle = (left+right)/2为分界线,逐步缩小查询范围,直到查询范围中无元素。
class Solution {
public:
int search(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 { // nums[middle] == target
return middle;
}
}
return -1;
}
};
注意事项:以[left,right]为查询范围和[left,right)查询范围的下标更新方式和循环终止条件存在差异,但原理相同。比如循环终止条件均为查询范围内是否有元素。
27.移除元素
题目链接:27.移除元素
暴力解法:遍历数组,找到需要被移除的元素,然后数组中将该元素后面的元素向前移一位。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int sum = nums.size();
for(int i = 0; i < sum;i++){
if(nums[i] == val){
for(int j = i; j < sum-1; j++){
nums[j]=nums[j+1];
}
sum--;
i--;
}
}
return sum;
}
};
快慢指针法:用快指针向前遍历,用慢指针更新目标数组中的元素。
class Solution {
public:
int removeElement(vector<int>& nums, int val){
int slowIndex = 0;
for(int fastIndex = 0; fastIndex < nums.size();fastIndex++){
if(nums[fastIndex]!=val){
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
注意事项:慢指针的“停更”原则为找到需要“跳过记录”的数组元素。
977.有序数组的平方
题目链接:977.有序数组的平方
暴力解法:先将数组中各元素平方,然后将平方数组排序。
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;
}
};
双指针法:由于原数组是有序的,最小的负数的平方结果是负数中平方所能出现的最大值,故在数组起始位置和结束位置分别设置指针向数组中间进行遍历。定义一个与原数组长度相同的新数组result来记录目标数组,当起始指针位置的元素的平方大于结束指针位置的元素的平方时,以起始指针位置的元素的平方来更新目标数组。
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;
}
};