提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
1.学习有序数组平方的双指针算法
2.滑动窗口算法
3.螺旋矩阵操作
提示:以下是本篇文章正文内容,下面案例可供参考
一、有序数组平方(力扣977)
实现思想1:先对数组平方然后使用快速排序
1.力扣写法
class Solution {
public:
void quick_sort(vector<int> &array, int l, int r){
if(l >= r) return;
int x = array[(l+r)/2], i = l-1, j = r+1;
while(i < j){
do i++; while(x > array[i]);
do j--; while(x < array[j]);
if (i < j) swap(array[i], array[j]);
}
quick_sort(array, l, j);
quick_sort(array, j+1, r);
}
vector<int> sortedSquares(vector<int>& nums) {
int size = nums.size();
for (int i = 0; i < size; i++){
nums[i] = nums[i]*nums[i];
}
quick_sort(nums, 0, nums.size()-1);
return nums;
}
};
2.2.自行创建数组并实现有序数组平方
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
//第一种方式,先对数组进行平方,然后对平方的结果进行排序
void function(vector<int> &array){
int size = array.size();
for (int i = 0; i < size; i++){
array[i] = pow(array[i], 2);
}
}
void quick_sort(vector<int> &array, int l, int r){
if(l >= r) return;
int x = array[(l+r)/2], i = l-1, j = r+1;
while(i < j){
do i++; while(x > array[i]);
do j--; while(x < array[j]);
if (i < j) swap(array[i], array[j]);
}
quick_sort(array, l, j);
quick_sort(array, j+1, r);
}
int main(void){
vector<int> array = {3, 1, 2, 5, 4};
function(array);
quick_sort(array, 0, 4);
for (auto p : array) cout << p << ' ';
}
实现思想2:使用双指针算法
1.力扣写法
class Solution {
public:
vector<int> sortedSquares(vector<int>& nums) {
vector<int> result;
int k = nums.size()-1;
result.resize(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[i]*nums[i];
i++;
}
else{
result[k--] = nums[j]*nums[j];
j--;
}
}
return result;
}
};
2.自行创建数组并实现有序数组平方
#include <iostream>
#include <vector>
using namespace std;
void function(vector<int> &nums, vector<int> &result){
int k = nums.size() - 1;
//将result数组的大小设置成和nums数组一样大,并把数组值全部初始成0
result.resize(nums.size(), 0);
for (int i = 0, j = nums.size() - 1; i <= j;){
//因为数组是有序的,所以值一定是依次从两边取值
//当nums[i]的平方大于nums[j]的平方的时候
//将num[i]的平方存到result数组最后一位否则就将nums[j]平方存入
if (nums[i]*nums[i] >= nums[j]*nums[j]){
result[k--] = nums[i]*nums[i];
i++;
}
else{
result[k--] = nums[j]*nums[j];
j--;
}
}
}
int main(void){
//这个nums数组一定是有序的才能使用上面的方法
vector<int> nums = {-4, -3, -1, 0, 1, 3, 5};
vector<int> result;
function(nums, result);
//展示result数组
for (auto p: result){
cout << p << ' ';
}
return 0;
}
二、长度最小的子数组(力扣209)
实现思想:使用双指针i和j,i用来表示最小子数组的头,j用来表示最小子数组的尾,只要目前最小子数组中的元素和达不到要求,j就向后移动,直到其中的元素和达到要求的数值,此时将该子数组的长度记录下来,并将i后移寻找下一个达标的子数组,如果找到长度更小的子数组就将之前的长度覆盖。
1.力扣写法
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i = 0;
int sum = 0;
int sublength;
int result = INT32_MAX;
for(int j = 0; j < nums.size(); j++){
sum += nums[j];
while(sum >= target){
sublength = j - i + 1;
result = result< sublength ? result : sublength;
sum -= nums[i++];
}
}
return result == INT32_MAX ? 0 : result;
}
};
2.自行创建数组实现长度最小的子数组
#include <iostream>
#include <vector>
using namespace std;
int function (vector<int> &nums, int s){
int i = 0; // 起点指针
int sum = 0;// 记录当前数组的和有没有达到目标值(sum是实时更新的)
int sublength;// 记录最小数组的长度(sublength是实时更新的)
int result = INT32_MAX;// result用来保留最长度小的一个sublength
for (int j = 0; j < nums.size(); j++){ //j是终点指针
sum += nums[j];
while(sum >= s){
sublength = j - i + 1;//计算当前达标的数组长度
//如果result < sublength就让result = result否则就让 result = sublength
result = result < sublength ? result : sublength;
sum -= nums[i++];
}
}
//如果result值没有改变就说明数组中的所有值加起来都达不到s, 返回0
//如果result值改变了就返回result的值
return result == INT32_MAX ? 0 :result;
}
int main(void){
vector<int> nums = {2, 3, 1, 2, 4, 3};
//检查数组中使值加起来大于等于7得最小长度的数组
//在这个数组中就是[4, 3]
int result = function(nums, 7);
cout << result;
return 0;
}
三、螺旋矩阵||(力扣59)
实现思想:每一个边的处理都遵循左闭右开的原则,n - offset表示每一次循环的边界
1.力扣写法
class Solution {
public:
vector<vector<int>> generateMatrix(int n) {
vector<vector<int>> res(n, vector<int>(n, 0));
int startx = 0, starty = 0;
int loop = n / 2;
int count = 1;
int mid = n / 2;
int offset = 1;
int i, j;
while(loop--){
i = startx;
j = starty;
for (j = starty; j < n-offset; j++){
res[startx][j] = count++;
}
for (i = startx; i < n-offset; i++){
res[i][j] = count++;
}
for (j; j > starty; j--){
res[i][j] = count++;
}
for(i; i > startx; i--){
res[i][j] = count++;
}
startx++;
starty++;
offset++;
}
if (n%2){
res[mid][mid] = count;
}
return res;
}
};
2.自行实现二维数组的创建赋值和输出
#include <iostream>
#include <vector>
using namespace std;
void function(vector<vector<int>> &res, int n){
int startx = 0, starty = 0;//x和y的开始位置
int offset = 1; //控制每一条边的遍历长度,每次循环右边界收缩一位
int count = 1; //用来表示打印的数字
int loop = n / 2; //用来表示需要循环的次数
int mid = n/2; // 矩阵中间的位置,例如:n为3, 中间的位置就是(1,1),n为5,中间位置为(2, 2)
int i, j;
while(loop--){
i = startx;
j = starty;
//循环创建上边
for (j = starty; j < n - offset; j++){
res[startx][j] = count++;
}
//创建右边
for (i = startx; i < n - offset; i++){
res[i][j] = count++;
}
//创建下边
for (;j > starty; j--){
res[i][j] = count++;
}
//创建左边
for (; i > startx; i--){
res[i][j] = count++;
}
//在创建完一圈后更新起始位置
//并且将offset增加
startx++;
starty++;
offset++;
}
//如果边是奇数的 那么中间的点就需要单独填充
if(n%2){
res[mid][mid] = count;
}
}
int main(void){
int n;
cin >> n;
//创建二位数组vector
vector<vector<int>> res(n, vector<int>(n, 0));
function(res, n);
//将创建的二维数组进行输出
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cout << res[i][j] << " ";
}
cout << endl;
}
return 0;
}