每日一题 0206

(2022.02.06)每日一题 唯一元素的和以及黄金矿工

补充昨天没做的每日一题。

先做简单的,2月6日的每日一题,第一眼很简单,哈希表存储,需要遍历两次,当时想到了可以状态的不同来表示,查看题解,果然有这种做法。直接上代码。状态方式就是,第一次遍历到数字全部加到答案中去,第二次遍历时就从答案中减去,要灵活变通。

//mine
class Solution {
public:
    int sumOfUnique(vector<int>& nums) {
        unordered_map<int,int> count;
        int res = 0;
        for(int num:nums){
            count[num] += 1;
        }

        for(auto& temp:count){
            if(temp.second == 1){
                res += temp.first;
            }
        }
        return res;
    }
};

//official
/*
我们可以赋给每个元素三个状态:
0:该元素尚未被访问;
1:该元素被访问过一次;
2:该元素被访问超过一次。
我们可以在首次访问一个元素时,将该元素加入答案,然后将该元素状态标记为1。在访问到一个标记为1 的元素时,由于这意味着该元素出现不止一次,因此将其从答案中减去,并将该元素状态标记为2。
*/
class Solution {
public:
    int sumOfUnique(vector<int> &nums) {
        int ans = 0;
        unordered_map<int, int> state;
        for (int num : nums) {
            if (state[num] == 0) {
                ans += num;
                state[num] = 1;
            } else if (state[num] == 1) {
                ans -= num;
                state[num] = 2;
            }
        }
        return ans;
    }
};

接下来是黄金矿工的题,这种题,当时一看到就是用回溯。

首先先记录几个该题的几个值得注意的点(特指我自己嗷,太菜了):

  1. 利用一个二维数组来表示上下左右四个方向的操作,第一维表x的方向,第二维表y的方向。
  2. 访问一次的操作通过访问完置0,之后恢复来达成。
  3. vector<vector<int>> grid获取行列数时,行数为grid.size(),列数为grid[0].size().这个我真的脑抽啊,你在第一维选取元素的时候,就已经选中了嵌套的数组了,就是第二维的元素个数了,当你不选取元素,才是第一维的元素个数
  4. 有个问题就是传值和深拷贝的关系?

写完对回溯还是懵懵懂懂,但是确实理解更深刻了,但是我还无法用语言总结出来,明天开始刷二叉树,系统一点。

class Solution {
private:
    //先定义上下左右的二维数组表示
    static constexpr int dirs[4][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    int gold = 0;
    int maxM = 0;

public:
    int getMaximumGold(vector<vector<int>>& grid) {
        //获取行列数目
        int m = grid.size();
        int n = grid[0].size();
        //遍历找到初始grid不为0的格子,开始进行搜索
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] != 0) {
                    backtracking(i, j, grid, m, n,gold);
                }
            }
        }
        return maxM;
    }

    void backtracking(const int &i, const int &j, vector<vector<int>>& grid, const int& m, const int& n,int gold) {
        int rec = grid[i][j];
        gold += grid[i][j];
        grid[i][j] = 0;
        //在你进行四个方向尝试的时候,起点就不能再被选取,所以要等四个方向全部走完,起点数据才能恢复,即grid[i][j] = rec;
        for (int temp = 0; temp < 4; temp++) {
            int nx = i + dirs[temp][0];
            int ny = j + dirs[temp][1];
            if (nx >= 0 && nx < m && ny >= 0 && ny < n && grid[nx][ny] != 0) {
                backtracking(nx, ny, grid, m, n,gold);
            }
            maxM = max(maxM, gold);
            
        }
        //撤销操作
        grid[i][j] = rec;

    }
};
posted @ 2022-02-06 23:48  kusola  阅读(42)  评论(0)    收藏  举报