算法训练——数组操作

算法训练——数组操作

写在开始

这是一个比较长久的计划,希望自己能够坚持。我会尽量每日(工作日)在github上打卡算法题,每做完一种题型后我会来CSDN总结一下,复盘在这类题型中遇到的问题,以及常用的解题技巧等等。
今天先总结下目前解决完的第一类题型:数组

涉及到的题目,在leetcode中可以找到对应题目:
在这里插入图片描述
完整代码及对应题解已上传至github,链接如下:
https://github.com/Aysamu/Algorithms-NoteBook/tree/master/%E7%8E%8B%E6%B3%BD%E6%9D%BE/%E6%95%B0%E7%BB%84

经典题目总结:

题目名称:54. 螺旋矩阵
题目链接:https://leetcode-cn.com/problems/spiral-matrix/
在这里插入图片描述
解题思路:
这一题乍一看有点难度,不是很好想。关键你需要确定这个遍历何时结束,当遇到边界的时候如何转弯。官方题解给的很一般,看到了一篇优质题解:从边界入手,规定每次的路径都是右下左上循环,当有边界碰到一起的时候,所有元素均被遍历到,循环截至。
下面附上完整代码:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector <int> ans;
        if(matrix.empty()) return ans; //若数组为空,直接返回答案
        int u = 0; //赋值上下左右边界
        int d = matrix.size() - 1;
        int l = 0;
        int r = matrix[0].size() - 1;
        while(true)
        {
            for(int i = l; i <= r; ++i) ans.push_back(matrix[u][i]); //向右移动直到最右
            if(++ u > d) break; //重新设定上边界,若上边界大于下边界,则遍历遍历完成,下同
            for(int i = u; i <= d; ++i) ans.push_back(matrix[i][r]); //向下
            if(-- r < l) break; //重新设定有边界
            for(int i = r; i >= l; --i) ans.push_back(matrix[d][i]); //向左
            if(-- d < u) break; //重新设定下边界
            for(int i = d; i >= u; --i) ans.push_back(matrix[i][l]); //向上
            if(++ l > r) break; //重新设定左边界
        }
        return ans;
    }
};

题目名称:118. 杨辉三角
题目链接:https://leetcode-cn.com/problems/pascals-triangle/
解题思路:
较为常见的一类题型,仔细观察可以发现,将三角中的每一行左对齐,空余位置补零,则可形成一个numRows*numRows的矩阵。对于矩阵中的一个元素array[i] [j]来说,其值等于array[i-1] [j]加上array[i-1] [j-1]。若下标越界则按零处理,注意杨辉三角的尖尖,也就是矩阵的[0] [0]号位需要事先置为一。
完整代码:

class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> answer;
        int array1[numRows][numRows]; //将杨辉三角向左对齐,空的位置补零,则成为一个矩阵,每个元素等于array1[i-1][j-1]+array1[i-1][j];
        memset(array1,0,sizeof(array1));
        array1[0][0]=1; //杨辉三角的尖尖需要初始化为1。
        for(int i=1;i<numRows;i++){
            for(int j=0;j<numRows;j++){
                int left_head=0;
                int right_head=0;
                if(i-1>=0){  //注意边界情况下的求值
                    right_head= array1[i-1][j];
                    if(j-1>=0){left_head=array1[i-1][j-1];}
                }
                array1[i][j] = left_head+right_head;
            }
        }
        for(int i=0;i<numRows;i++){
            vector<int> temp;
            for(int j=0;j<=i;j++){
                temp.push_back(array1[i][j]);
            }
            answer.push_back(temp);
        }
        return answer;

    }
};

题目名称:453.最小操作次数使数组元素相等
题目链接:https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements/
解题思路:最初我的思路较为简单,不停的进行排序,将前n-1个数加一,直到全部相等为止,但是时间超限。优秀解法为数学法,将一个数以的所有数加一,等于把这个数减一。计算所有元素减小到最小值的次数总和即可。
完整代码:

class Solution {
public:
    int minMoves(vector<int>& nums) {
        int length = nums.size();
        sort(nums.begin(),nums.end());
        int min=nums[0];
        int sum=0;
        for(int i=0;i<length;i++){
            sum+=nums[i]-min;
        }
        return sum;
    }
};

题目名称:645. 错误的集合
题目链接:https://leetcode-cn.com/problems/set-mismatch/
解题思路:这个做法很新奇,声明一个和原数组一样大小的数组,遍历原数组,利用原数组中的数组值作为新数组的下标,对应数值加一。遍历一遍以后,新数组值为零处代表该下标元素缺少,为2处代表冗余。
完整代码:

class Solution {
public:
    vector<int> findErrorNums(vector<int>& nums) {
            vector<int> n(nums.size(),0);
            vector<int> res(2,0);
            for(int i=0;i<nums.size();i++){
                n[nums[i]-1]++;
            }
            for(int i=0;i<nums.size();i++){
                if(n[i]==2) res[0]=i+1;
                else if(n[i]==0) res[1]=i+1;
            }
            return res;
    }
};

常用方法总结

Vector数组用法集合

初始化:
一维数组:vector<int> n(nums.size(),0) ,数组大小nums.size(),初始值全部为零。
二维数组:vector<vector<int>> matrix(r,vector<int>(c)),前面是行数后面是列数,共r行c列,这里初始化的方法比较新奇。
动态添加内容:
不需要事先声明数组大小,利用push_back语句将元素压入vector数组中。

vector<int> temp;
for(int i=0;i<m;i++){
      for(int j=0;j<n;j++){
          temp.push_back(nums[i][j]);
     }
}

周洋学长总结的vector用法,非常详细,原帖在这里:
https://blog.csdn.net/qq_43549752/article/details/90740440?spm=1001.2014.3001.5501

求数组的大小:

一维数组:int m=nums.size();
二维数组:

int m=nums.size();    //矩阵的行数
int n=nums[0].size(); //矩阵的列数

数组排序:

语句操作,无需二次赋值

sort(nums.begin(),nums.end());

数组拷贝:

将newArr数组中的内容拷贝至nums数组中,注意赋值

nums.assign(newArr.begin(), newArr.end());

*注:文本部分代码来自leetcode优秀题解,仅总结归纳使用,侵删

created by ZesongWang

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值