1. 27. 移除元素 (Remove Element)
题目要求:
给定数组 nums 和值 val,移除所有数值等于 val 的元素,返回移除后数组的新长度 k。要求原地修改数组,使得前 k 个元素为不等于 val 的元素。
解题思路:
- 使用双指针的方法:一个指针遍历数组,另一个指针标记不等于
val的元素。 - 每次遇到不等于
val的元素时,将其放置到前面的空位,并更新指针。 - 返回最后标记的不等于
val的元素数量。
解题过程:
解法一:
cpp
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int n = nums.size(); //元素个数
int i = 0;
while (i < n) {
if (nums[i] == val) {
for (int j = i; j < n -1; j++) {
nums[j] = nums [j + 1];
} //依次前移一位
n--; //去掉移动到最后的元素
} else {
i++;
}
}
return n; //返回最终的元素个数
}
};
//暴力移动
解法二:
cpp
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int s = 0; //
for (int f = 0; f < nums.size(); f++) { //快指针遍历
if (nums[f] != val) { //查找非val元素
nums[s] = nums[f]; //快指针遍历查到非val元素,慢指针才会前进-->慢指针停止前进则下一个一定是非val元素的存放地址;
s++; //更换后再进行同步前进查询,s++记录非val元素个数
}
}
return s;
}
};
2. 704. 二分查找 (Binary Search)
题目要求:
在升序排列的整数数组 nums 中查找 target,若找到则返回其下标,否则返回 -1。要求时间复杂度为 O(log n)。
解题思路:
- 使用经典的二分查找方法:通过不断缩小查找范围,将目标与中间元素比较。
- 若目标等于中间元素,则返回该元素的下标。
- 否则,根据目标值与中间元素的大小关系更新左右边界,继续查找。
示例:
- 输入:
nums = [-1,0,3,5,9,12], target = 9→ 输出:4 - 输入:
nums = [-1,0,3,5,9,12], target = 2→ 输出:-1
约束条件:
- 数组元素不重复
- 数组长度
1 <= nums.length <= 10000 - 元素值范围
-9999 <= nums[i] <= 9999
解题过程:
解法一:
cpp
class Solution {
public:
int search(vector<int>& nums, int target) {
int sub = 0; //下标从0开始
for (auto i : nums) { //auto i : nums --- i 直接指向nums中的元素
if ( target == i) { //遍历元素依次比对目标元素
return sub; //找到则返回下标值
}
sub++; //本轮查询未找到,循环查找下一个元素
}
return -1; //循环结束未找到,则返回-1
}
};
解法二:
cpp
class Solution {
public:
int search(vector<int>& nums, int target) {
//int i = nums.size() - 1;//size()返回值为元素个数,size()-1直接匹配下标
for (int i=0; i < nums.size(); i++) {
if ( nums[i] == target ) {
return i;
}
}
return -1;
}
};
解法三:
cpp
class Solution {
public:
int search(vector<int>& nums, int target) {
int i = 0,j = nums.size() - 1;
while(i <= j) {
int m = (i + j) / 2;
if(nums[m] == target) {
return m;
}else if (nums[m] > target) {
j = m - 1;
}else {
i = m + 1;
}
}
return -1;
}
};
//奇数:3个-->i=0.j=2,mid=(i+j)/2-->j=mid||i=mid;
//偶数:4个-->i=0,j=3,mid=(i+j)/2-->i=mid+1||j=mid;mid=(i+j)/2+1-->i=mid,j=mid-1
//不用考虑奇偶,不越界溢出即可
解法四:
cpp
class Solution {
public:
int search(vector<int>& nums, int target) {
int i = 0, j = nums.size();
while (i < j) {
int m = i + (j - i) / 2;
if (nums[m] > target) { //左区间
j = m;
} else if (nums[m] == target) {
return m;
} else {
i = m + 1; //左区间
}
}
return -1;
}
};
3. 977. 有序数组的平方 (Squares of a Sorted Array)
题目要求:
给定一个非递减顺序排序的整数数组 nums,返回每个数字平方后按非递减顺序排序的数组。要求设计 O(n) 时间复杂度的算法。
解题思路:
- 使用双指针方法:一指针从左边开始,另一指针从右边开始。
- 计算左右指针所指元素的平方,较大的平方先放入结果数组的末尾。
- 根据左右指针的比较,逐步填充结果数组。
示例:
- 输入:
[-4,-1,0,3,10]→ 输出:[0,1,9,16,100] - 输入:
[-7,-3,2,3,11]→ 输出:[4,9,9,49,121]
约束条件:
1 <= nums.length <= 10^4-10^4 <= nums[i] <= 10^4nums已按非递减顺序排序
解题过程:
解法一:
cpp
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;
}
};
解法二:
cpp
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
int n = nums.size();
vector <int> newans(n);
int i = 0, j = n - 1;
for (int p = n - 1; p >= 0; p--) {
if (nums[i] * nums[i] > nums[j] * nums[j]) {
newans[p] = nums[i] * nums[i];
i++;
} else {
newans[p] = nums[j] * nums[j];
j--;
}
}
return newans;
}
};