5月29日刷题笔记——数组

5月29日刷题笔记——数组

题目1:350. 两个数组的交集 II(简单题)

我的题解:

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        unordered_map<int, int> m;
        vector<int> b(1000);
        vector<int> ans;
        int i = 0;
        int j = 0;
        for(i = 0; i < nums1.size(); i++){
            for(j = 0; j < nums2.size(); j++){
                if(nums1[i] == nums2[j] && b[j] != 1){
                    m[nums1[i]]++;
                    b[j] = 1;
                    break;
                }
            }
        }
        i = 0;
        for(auto a:m){
            if(a.second > 1){
                for(j = 0; j < a.second; j++){
                    ans.push_back(a.first);
                }
            }
            if(a.second == 1){
                ans.push_back(a.first);
            }
        }
        return ans;
    }
};

总结知识点:

1.push_back()函数,刚开始因为未知数组长度,定的1000,但是后面一直会补0.后面看了评论区,学的push_back()函数解决了这个问题。函数是在vector最后插入一个元素,也可以用在string上。

2.哈希表中a.first取key,a.second取value。

参考文献:

1.c++中push_back()函数的用法:https://blog.csdn.net/qq_36955294/article/details/110954308

参考题解的哈希表解法:

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        // 保证nums1是两个数组中元素最少的,方便后面遍历nums1添加到哈希表中,目的为降低空间复杂度
        if (nums1.size() > nums2.size()) {
            return intersect(nums2, nums1);
        }
        unordered_map <int, int> m;
        // 记录数组nums1中的元素及元素的出现次数
        for (int num : nums1) {
            ++m[num];
        }
        vector<int> intersection;
        for (int num : nums2) {
            // count查找哈希表内是否存在key为num的键值对为1则找到,为0则没找到
            if (m.count(num)) {
                // 使用push_back()函数将元素插入容器
                intersection.push_back(num);
                // 配对成功,哈希表内该元素的出现次数-1
                --m[num];
                // 如果该元素的出现次数为0,说明该元素已经全部配对插入过了,
                if (m[num] == 0) {
                    // 使用erase()函数删除key为num的键值对
                    m.erase(num);
                }
            }
        }
        return intersection;
    }
};

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/intersection-of-two-arrays-ii/solution/liang-ge-shu-zu-de-jiao-ji-ii-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

根据题解复现代码:

用时8ms,比刚刚快了4ms。内存消耗10.2MB。

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        /* 思路:遍历元素数较少的数组,将其加入哈希表内。遍历长数组,若哈希表内存在与之配对的元素,
        ** 则将该元素push_back至容器内,哈希表内该元素的出现次数-1
        */
        // 1.比较两数组的长度,确保nums1是元素数量最少的数组,如果不是,则将两个函数置换重新调用该函数
        if(nums1.size() > nums2.size()){
            return intersect(nums2, nums1);
        }
        // 定义一个哈希表存储nums1内的元素及元素出现次数
        unordered_map<int, int> m;
        // 遍历数组nums1,将其加入哈希表内
        for(auto i:nums1){
            m[i]++;
        }
        // 定义一个容器存放最终结果
        vector<int> intersection;
        // 遍历数组nums2
        for(auto i:nums2){
            // 如果哈希表内存在,此时nums2数组内该元素的键值对,说明配对上了
            if(m.count(i)){
                // 将元素push_back到容器尾部,并将该元素的出现次数-1
                intersection.push_back(i);
                m[i]--;
                // 哈希表内该元素的出现次数为0时,说明该元素全部配对完成。则删除该键值对
                if(m[i] == 0){
                    m.erase(i);
                }
            }
        }
        return intersection;
    }
};

总结新知识点:

1.erase()函数可以删除元素。

题目2:121. 买卖股票的最佳时机(简单题)

我的题解:

刚开始用的暴力解法,超出时间限制了,然后看了评论动态规划的提示,成功啦。

思路即:前i天的最大收益 = max{前i-1天的最大收益,第i天的价格-前i-1天中的最小价格}

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int i = 0;
        // int j = 0;
        int len = prices.size();
        int maxPrice = 0;
        int minPrice = prices[0];
        // for(i = len - 1; i > 0; i--){
        //     for(j = 0; j < i; j++){
        //         maxPrice = max(maxPrice, prices[i] - prices[j]);
        //     }
        // }
        for(i = 0; i < len; i++){
            minPrice = min(minPrice, prices[i]);
            maxPrice = max(maxPrice, prices[i] - minPrice);
        }
        return maxPrice;
    }
};

总结:

1.动态规划的思路还要多思考。

题目3:566. 重塑矩阵(简单题)

我的题解:

class Solution {
public:
    vector<vector<int>> matrixReshape(vector<vector<int>>& mat, int r, int c) {
        // 获取原矩阵的行和列
        int row = mat.size();
        int col = mat[0].size();
        if(row * col != r * c) return mat;
        vector<vector<int>> newMatrix(r,vector<int>(c));
        int i,j = 0;
        int k = 0;
        int h = 0;
        for(i = 0; i < row; i++){
            for(j = 0; j < col; j++){
                if(k < r && h < c){
                    newMatrix[k][h] = mat[i][j];
                    h++;
                    if(h == c){
                        k++;
                        h = 0;
                    }
                }
            }
        }
        return newMatrix;
    }
};

总结知识点:

1.二维数组a求行个数:a.size(); 求列个数: a[0].size();

参考题解:

题解思路:1.将二维数组映射为一维数组。 2.将一维数组映射为r行c列的二维数组。

代码如下:


class Solution {
public:
    vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
        int m = nums.size();
        int n = nums[0].size();
        // 两个矩阵元素个数不同,无法重塑
        if (m * n != r * c) {
            return nums;
        }

        vector<vector<int>> ans(r, vector<int>(c));
        for (int x = 0; x < m * n; ++x) {
            /* 1.第x个元素在nums中对应的下标为(x/n, x%n),其中n为原数组的列数。
            ** 2.第x个元素在重塑矩阵中对应的下标为(x/c, x%c),其中c为新矩阵的列数。
            */
            ans[x / c][x % c] = nums[x / n][x % n];
        }
        return ans;
    }
};

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/reshape-the-matrix/solution/zhong-su-ju-zhen-by-leetcode-solution-gt0g/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

根据题解代码复现:

class Solution {
public:
    vector<vector<int>> matrixReshape(vector<vector<int>>& mat, int r, int c) {
        // 获取原矩阵的行列数
        int m = mat.size();
        int n = mat[0].size();
        // 判断两矩阵元素个数是否相同
        if(m*n != r*c) return mat;
        // 新建二维数组存放重塑矩阵
        vector<vector<int>> ans(r,vector<int>(c));
        // 循环取原矩阵内的元素赋值给新矩阵
        for(int i = 0; i < m * n; i++){
            ans[i / c][i % c] = mat[i / n][i % n];
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值