HOT100打卡—day7—【数组&矩阵】—23.8.13

【数组】

1 53. 最大子数组和

53. 最大子数组和

方法1:前缀和 + 一点技巧(好像是贪心):一个记录当前遍历位置前的最小前缀和。再利用一个int记录差值最大的值

我一开始只想到前缀和,但是O(n^2)超时,后来找到个题解加上一点技巧就可以在前缀和的 基础上降到O(n)。

class Solution
{
public:
    int maxSubArray(vector<int> &nums)
    {
        int sum[100010];
        memset(sum,sizeof(sum),0);

        for(int i = 1; i <= nums.size();i++)  // 1...n
            sum[i] = sum[i-1] + nums[i-1];

        
        int low = INT_MAX;
        int dif = INT_MIN;
        for(int i = 0; i <= nums.size();i++) /// sum[j] - sum[i] 并且(j>i)求个max
        {
            // 一个记录当前遍历位置前的最小前缀和
            // 再利用一个int记录差值最大的值
            dif = max(dif , sum[i] - low);  // 目前最大的差值
            low = min(low , sum[i]); //必须要先更新max,再更新min,防止min和i重合
        }
        if(nums.size() == 1)return nums[0];
        return dif;
    }
};

方法2:动态规划法:

dp做起来比上面那个方法轻松一百倍,我服了,上面那个有点技巧还易错,dp就是个极简单的问题。ac:

class Solution {
public:
    // dp做一次
    int dp[100010]; // 以i结尾的连续子数组最大的和
    /*
        if(dp[j-1] >  0)
            dp[j] = dp[j-1] + nums[j];
        else dp[j] = nums[j];

        dp[0] = nums[0]

        j++;
    */
    int maxSubArray(vector<int>& nums) {
        dp[0] = nums[0];
        int ans = dp[0];
        for(int j = 1; j < nums.size();j++)
        {
            if(dp[j-1] >  0)
                dp[j] = dp[j-1] + nums[j];
            else dp[j] = nums[j];
            ans = max(ans,dp[j]);
        }
        return ans;
    }
};

2 56. 合并区间

56. 合并区间

典型贪心,AC代码:

class Solution {
public:
    static bool cmp(vector<int> a, vector<int> b)
    {
        return a[0] < b[0];
    }
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        // 贪心
        sort(intervals.begin(),intervals.end(),cmp);

        vector<vector<int>> ans;

        vector<int> tmp;

        int l = intervals[0][0];
        int r = intervals[0][1];
        
        for(int i = 1; i < intervals.size();i++)
        {
            if(intervals[i][0] > r)
            {
                tmp.clear();
                tmp.push_back(l);
                tmp.push_back(r);
                ans.push_back(tmp);

                l = intervals[i][0];
                r = intervals[i][1];
            }
            else if(intervals[i][1] > r) r = intervals[i][1];
        }

        tmp.clear();
        tmp.push_back(l);
        tmp.push_back(r);
        ans.push_back(tmp);
        return ans;
    }
};

3 189. 轮转数组(多种解法,todo)

189. 轮转数组

一种写法的AC代码:

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        //法1:再开一个vector 存完之后替换nums
        //法2:把前面的push_back到后面 然后全部前移动,resize
        //法3:
        int size = nums.size();
        k %= size;  // 注意k的取值范围不是 小于size
        for(int i = 0; i < size - k;i++)
            nums.push_back(nums[i]);
        for(int i = 0,j = size - k; i < size;i++,j++)
            nums[i] = nums[j];
        nums.resize(size);
        return;
    }
};

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

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

用了pat学到的:左右两次遍历大法

AC代码:

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) 
    {
        vector<int> ans(nums.size());

        ans[0] = 0;
        ans[1] = nums[0];

        for(int i = 2; i < nums.size();i++)
            ans[i] = nums[i-1]*ans[i-1];
        
        int tmp = 1;
        for(int i = nums.size()-1; i >= 0; i--)
        {
            if(i == nums.size()-1)
            {
                
            }
            else if(i == 0)
            {
                ans[i] = tmp;
            }
            else
            {
                ans[i] = tmp*ans[i];
            }
            tmp *= nums[i];
            cout << i << " " << tmp << endl;
        }
        return ans;
    }
};

// 2 3 4

【矩阵】

1 73. 矩阵置零

73. 矩阵置零

我的方法和题解方法见注释,AC代码:

class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        // 我的方法:
        // 时间复杂度O(m*n) 空间复杂度O(m+n)
        // 遍历一遍 找到0位置的行列存起来
        // 再遍历一次 画0


        // 题解:
        /*
        思路二: 用O(1)O(1)O(1)空间
        关键思想: 用matrix第一行和第一列记录该行该列是否有0,作为标志位
        但是对于第一行,和第一列要设置一个标志位,为了防止自己这一行(一列)也有0的情况.注释写在代码里,直接看代码很好理解!
        */

        unordered_set<int> line;
        unordered_set<int> vol;
        for(int i = 0; i < matrix.size();i++)
        {
            for(int j = 0; j < matrix[i].size();j++)
            {
                if(matrix[i][j] == 0)
                {
                    line.insert(i);
                    vol.insert(j);
                }
            }
        }
        for(auto i : line)
        {
            for(int j = 0; j < matrix[i].size();j++)
                matrix[i][j] = 0;
        }
         for(auto i : vol)
        {
            for(int j = 0; j < matrix.size();j++)
                matrix[j][i] = 0;
        }
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值