|
文章目录
- 1. 有序数组的平方
- 2. 长度最小的最数组
- 3. 螺旋数组II
1. 有序数组的平方
有序数组的平方
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums)
{
int n = nums.size();
// 以0为分割线的话,可以将该数组分成两个子数组,并且都是有序的
// 直接将双指针分别初始化在 nums 的开头和结尾,相当于合并两个从大到小排序的数组
// 这时我们就可以利用合并两个有序数组的方法解决本题了
int i = 0, j = n - 1; // 头和尾
int p = n - 1;
vector<int> res(n);
while(i <= j)
{
// 比较绝对值大小
if(abs(nums[i]) < abs(nums[j]))
{
res[p] = nums[j] * nums[j];
j--;
}
else
{
res[p] = nums[i] * nums[i];
i++;
}
p--;
}
return res;
}
};
类似题目:
- 合并两个有序数组
class Solution {
public:
void merge(vector<int>& nums1, int m, vector<int>& nums2, int n)
{
// 从后向前遍历,因为需要将结果存放到nums1中,从前向后会覆盖原始数据
int i = m - 1, j = n - 1;
int p = nums1.size() - 1;
while(i >= 0 && j >= 0)
{
// 此时有点类似合并两个有序链表的思路
if(nums1[i] > nums2[j])
{
nums1[p] = nums1[i];
i--;
}
else
{
nums1[p] = nums2[j];
j--;
}
p--;
}
// 因为本身就是将结果存放到nums1中的,所以只需要考虑nums2中剩余的元素
while(j >= 0)
{
nums1[p] = nums2[j];
j--;
p--;
}
}
};
- 合并两个有序链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2)
{
// 因为合并两个有序链表会生成一条新链表,所以定义虚拟头节点会更简单
ListNode* newnode = new ListNode(-1), *p = newnode;
ListNode* p1 = list1, *p2 = list2;
while(p1 != nullptr && p2 != nullptr)
{
if(p1->val < p2->val)
{
p->next = p1;
p1 = p1->next;
}
else
{
p->next = p2;
p2 = p2->next;
}
p = p->next;
}
if(p1 != nullptr)
p->next = p1;
if(p2 != nullptr)
p->next = p2;
return newnode->next;
}
};
- 分隔链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x)
{
// 相当于生成了两条链表,一条中元素都小于x,另一条元素都不小于x
ListNode* newnode1 = new ListNode(-1), *p1 = newnode1;
ListNode* newnode2 = new ListNode(-1), *p2 = newnode2;
ListNode* p = head;
while(p != nullptr)
{
if(p->val < x)
{
p1->next = p;
p1 = p1->next;
}
else
{
p2->next = p;
p2 = p2->next;
}
p = p->next;
}
// 将链表2链接到链表1的末尾,记住别忘了将链表2的尾指向空
p1->next = newnode2->next;
p2->next = nullptr;
return newnode1->next;
}
};
2. 长度最小的最数组
长度最小的子数组
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums)
{
// 因为是正整数数组,没有负数,所以本题可以采用滑动窗口解题
int left = 0, right = 0;
int windowSum = 0; // 滑动窗口内的子数组和
int res = INT_MAX;
while(right < nums.size())
{
windowSum += nums[right];
right++;
// 判断左侧窗口什么时候收缩
while(windowSum >= target && left < right)
{
// 更新结果
res = min(res, right - left);
windowSum -= nums[left];
left++;
}
}
return res == INT_MAX ? 0 : res;
}
};
3. 螺旋数组II
螺旋数组II
class Solution {
public:
vector<vector<int>> generateMatrix(int n)
{
vector<vector<int>> res(n, vector<int>(n));
int num = 1;
int upper_bound = 0, lower_bound = n - 1; // 上下边界
int left_bound = 0, right_bound = n - 1; // 左右边界
while(num <= n * n) // num
{
// 上边界,从左往右遍历比较
if(upper_bound <= lower_bound)
{
for(int i = left_bound; i <= right_bound; i++)
{
res[upper_bound][i] = num++; // 后置++
}
// 上边界下移
upper_bound++;
}
// 右边界,从上向下遍历比较
if(left_bound <= right_bound)
{
for(int i = upper_bound; i <= lower_bound; i++)
{
res[i][right_bound] = num++;
}
// 右边界左移
right_bound--;
}
// 下边界,从右往左遍历比较
if(upper_bound <= lower_bound)
{
for(int i = right_bound; i >= left_bound; i--)
{
res[lower_bound][i] = num++;
}
// 下边界上移
lower_bound--;
}
// 左边界,从下向上遍历比较
if(left_bound <= right_bound)
{
for(int i = lower_bound; i >= upper_bound; i--)
{
res[i][left_bound] = num++;
}
// 左边界右移
left_bound++;
}
}
return res;
}
};