目录
283. 移动零
解析
题解
class Solution {
public:
void moveZeroes(vector<int>& nums) {
// 001_专题一_双指针_移动零_C++
// [0, dest] [dest + 1, cur - 1] [cur, n-1]
// 非0 0 待处理
for (int cur = 0, dest = -1; cur < nums.size(); cur++)
{
if (nums[cur] != 0)
swap(nums[++dest], nums[cur]);
// 交换dest + 1 位置,因为要向后移动,所以前置++了
// cur 同理,交换完之后需要向后移动,但是在循环中就会+1,所以不用自增
}
}
};
1089. 复写零
解析
题解
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
// 002_专题一_双指针_复写零_C++
// 1.先找到最后一个需要复写的数
int cur = 0, dest = -1, n = arr.size();
while(cur < n) // > 就说明越界了
{
if(arr[cur]) dest++;
else dest += 2;// 是0就要复写两遍
if (dest >= n-1) break;
cur++; // 向后移动
}
// 2.处理边界情况
// 单独处理这种情况就行了
if (dest == n)
{
// 因为只有0才会导致dest的越界,所以只需要考虑这一个n位置,即数组的后一个位置
// 当dest等于n位置的时候就说明会越界访问了
arr[n-1] = 0; // 将最后一个置为0
cur--; dest -= 2;
}
// 3.从后向前复写
while(cur >= 0)
{
if(arr[cur]) arr[dest--] = arr[cur--];
else
{
arr[dest--] = 0;
arr[dest--] = 0;
cur--;
}
}
}
};
202. 快乐数
解析
题解
class Solution {
public:
// 返回 n 这个数每一位上的平方和
int bitsum(int n) {
int sum = 0;
while (n) {
int t = n % 10;
sum += t * t;
n /= 10;
}
return sum;
}
bool isHappy(int n) {
// 003_专题一_双指针_快乐数_C++
int slow = n, fast = bitsum(n); // 用数来充当指针
while (slow != fast) {
slow = bitsum(slow);
fast = bitsum(bitsum(fast)); // 走两步
}
return slow == 1; // 是1即为快乐数,否则就不是
}
};
11. 盛最多水的容器
解析
题解
class Solution {
public:
int maxArea(vector<int>& height) {
// 004_专题一_双指针_盛最多水的容器_C++
// 利用单调性,使用双指针来解决问题
int left = 0, right = height.size() - 1, ret = 0;
while (left < right)
{
int v = min(height[left], height[right]) * (right - left); // 求出该范围内的最大水量
ret = max(ret, v); // 求出最大水量
height[left] > height[right] ? right-- : left++;// 移动指针
}
return ret;
}
};
611. 有效三角形的个数
解析
题解
class Solution {
public:
int triangleNumber(vector<int>& nums) {
// 005_专题一_双指针_有效三角形的个数_C++
// 解法 利用单调性,使用双指针算法解决问题
// 一. 先固定最大的数
// 二. 在最大的数的左区间内,使用双指针算法,快速统计出符合要求的三元组的个数
// 1.优化
sort(nums.begin(), nums.end());
// 2.利用双指针解决问题
int ret = 0;
// 固定最大的数
for (int i = nums.size() - 1; i >= 0; --i)
{
int left = 0, right = i - 1;
// 开始用双指针快速统计符合要求的三元组
// (因为前面已经排好序了所以只需要判断一次)
// 比如 a b c 只需要判断 a + b > c 即可判断是否是有效的三角形
while(left < right)
{
if (nums[left] + nums[right] > nums[i])
{
ret += right - left;
right--; // 这一区间都满足三元组,所以右指针前前移动
}
else left++;
}
}
return ret;
}
};