当前位置: 首页 > news >正文

leetcode-数组操作

238. 除自身以外的数组乘积

第一眼就是求总乘积,然后除自身,但题目要求不能用除法;
除自身以外,就是左右两边子数组,那不就是一个前缀乘积*后缀乘积吗,逻辑就出来,前缀i-1✖后缀i+1,就好了,不过注意两边极值,第一次写就是极值弄错了。

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int len = nums.size();
        vector<int> Lnum(len), Rnum(len);
        vector<int> result(len);
        Lnum[0] = nums[0];
        for(int i=1;i<len-1; i++){
            Lnum[i] = Lnum[i-1]*nums[i];
        }
        Rnum[len-1] = nums[len-1];
        for(int i=len-2; i>=0; i--)
            Rnum[i] = Rnum[i+1]*nums[i];
        for(int i=1;i<len-1;i++){
            result[i] = Rnum[i+1] * Lnum[i-1];
        }
        result[0] = Rnum[1];
        result[len-1] = Lnum[len-2];
        return result;
    }
};

41. 缺失的第一个正数

这题直接哈希了,map一下所有整数,先看有没有1,没有就直接返回1,其次遍历,找有没有比自己大1的键,就好了。

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        map<int,int> ma;
        int result = 0;
        for(const auto& n :nums){
            if(n>0 && ma.find(n)==ma.end())
                ma.insert(make_pair(n,1));
        }
        if(ma.find(1) == ma.end()){
                result = 1;
                return result;
        }
        for(const auto& m : ma){
            if(ma.find((m.first)+1) == ma.end()){
                result = (m.first)+1;
                cout<<m.first<<endl;
                break;
            }
        }
        return result;
    }
};

73. 矩阵置零

很容易想到,设置标志位表示原始值是不是0,然后两层for判断,是true就把行、列变为0。但实现起来怎么变为0呢,总不能再加一层for吧。纠结了半天;
其实,标志位不用设置二维,只需要确定某行、某列是否需要设置为0即可。

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        //vector<vector<bool>> flag(matrix.size(), vector<bool> (matrix[0].size(), false));
        vector<bool> row(matrix.size()), col(matrix[0].size());
        for(int i=0;i<matrix.size();i++)
            for(int j=0;j<matrix[0].size();j++)
                if(matrix[i][j] == 0)
                    row[i] = col[j] = true;
        for(int i=0;i<matrix.size();i++)
            for(int j=0;j<matrix[0].size();j++){
                if(row[i] ||  col[j]){
                   matrix[i][j] = 0;
                }
            }
        return;
    }
};

54. 螺旋矩阵

这是真考验数组边界判定的题,思路很直观,就是按照要求顺时针遍历,涉及4个边界。

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> result;
        if(matrix.empty())
            return result;
        int u=0, d=matrix.size()-1, l=0, r=matrix[0].size()-1;
        while(true){
            for(int i=l;i<=r;i++)
                result.push_back(matrix[u][i]);
            if(++u>d)
                break;
            for(int i=u;i<=d;i++)
                result.push_back(matrix[i][r]);
            if(--r<l)
                break;
            for(int i=r;i>=l;i--)
                result.push_back(matrix[d][i]);
            if(--d<u)
                break;
            for(int i=d;i>=u;i--)
                result.push_back(matrix[i][l]);
            if(++l>r)
                break;
        }
        return result;
    }
};

53. 最大子数组和

两种思路,动态规划,dp[i]表示i之前的最大子数组之和,每次取+或者不+num[i]的中较大值就好。然后遍历dp,找最大值就行。代码可以优化,求dp时顺便把result也更新。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int pre = 0;
        int result = nums[0];
        for(const auto& x : nums){
            pre = max(pre+x, x);
            result = max(result, pre);
        }
        return result;

    }
};

方法二,正常数组做法,不过就是求和时判断是否为负,如果为负值,那一定会影响最大子数组的和,因此一定不是答案,就更新和为0,重新开始求和;这里也坑,第一次写,想简化逻辑,结果写扯了,写的结果是所有正数之和。。。还感觉自己逻辑没问题,排查了半天。

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int result = INT_MIN;
        int add = 0;
        for(int i=0; i<nums.size(); i++){
            add += nums[i];
            if(add>result)
                result = add;
            if(add<0)
                add = 0;
            
        }
        return result;
    }
};

56. 合并区间

这题很直观,就是根据每个区间的左边界进行排序,然后依次判断即可。
第一个区间的左边界是可以确定的,所以第一个区间放进去。从第二个区间开始判断(i),如果i得左边界小于result得右边界,说明有重叠,更新back得右边界为最大值即可。如果大于,那就没重叠,把i区间放入result即可

class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());
        vector<vector<int>> result;
        result.emplace_back(intervals[0]);
        for(int i=1; i<intervals.size(); i++){
            if(result.back()[1] >= intervals[i][0])
                result.back()[1] = max(result.back()[1], intervals[i][1]);
            else
                result.emplace_back(intervals[i]);
        }
        return result;
    }
};

48.旋转矩阵

有点抽象了,两种方法,第一种,找出反转后得行列变换规律,matrix[row][col],在旋转后,它的新位置为 new [col][n−row−1]。两层for遍历就好;第二种方法原地反转,不借用辅助空间,顺时针旋转90=水平翻转+主对角线反转。第一次写有些难想到

class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        auto matrix_new = matrix;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                matrix_new[j][n - i - 1] = matrix[i][j];
            }
        }
        matrix = matrix_new;

    }
};

240. 搜索二维矩阵Ⅱ

直接暴力就不说了,优化的话,每行有个二分搜索吧

class Solution {
public:
    bool searchMatrix(vector<vector<int>>& matrix, int target) {
        for(const auto& row:matrix){
            auto it = lower_bound(row.begin(), row.end(), target);
            if(it != row.end() && *it==target)
                return true;
        }
        return false;
    }
};

相关文章:

  • LeetCode - #226 基于 Swift 实现基本计算器
  • 浙江大学:《DeepSeek——回望AI三大主义与加强通识教育》
  • 【每日学点HarmonyOS Next知识】对话框与导航冲突、富文本、字体大小、列表刷新、Scroll包裹文本
  • ROWNUM 与 ROW_NUMBER() OVER ()
  • llamafactory 微调教程
  • Python---函数
  • for...of的用法与介绍
  • 设计模式八股整理
  • 小白学习:提示工程(什么是prompt)
  • 计算机网络基础:简单渗透
  • sql语句分页的关键字是?
  • 【Linux】线程池
  • 解锁 Ryu API:从 Python 接口到 REST 设计全解析
  • Markdown 语法入门指南(VSCode 版)
  • NVSHMEM介绍、InfiniBand GPUDirect、和NVshmem使用案例说明
  • Scala编程_数组、列表、元组、集合与映射
  • GStreamer —— 2.18、Windows下Qt加载GStreamer库后运行 - “播放教程 6:音频可视化“(附:完整源码)
  • ubuntu挂载新硬盘
  • 5G工业路由器赋能无人码头,港口物流智能化管理
  • 大语言模型-语言模型发展历程
  • 外交部:国际社会广泛理解和支持中方不同意台参加世卫大会的决定
  • 杞支雅男评《1517》|放眼世界,立足德国
  • Offer触手可及,2025上海社会组织联合招聘专场活动正寻找发光的你
  • 欠债七十万后,一个乡镇驿站站长的中年心事
  • 一个多月来上海交大接连“牵手”三区,在这些方面进行区校合作
  • 广西北部湾国际港务集团副总经理潘料庭接受审查调查