LeetCode 第 157 场周赛 【玩筹码】【最长定差子序列】【黄金矿工】

5213. 玩筹码

数轴上放置了一些筹码,每个筹码的位置存在数组 chips 当中。

你可以对 任何筹码 执行下面两种操作之一(不限操作次数,0 次也可以):

  • 将第 i 个筹码向左或者右移动 2 个单位,代价为 0。
  • 将第 i 个筹码向左或者右移动 1 个单位,代价为 1。
    最开始的时候,同一位置上也可能放着两个或者更多的筹码。

返回将所有筹码移动到同一位置(任意位置)上所需要的最小代价。

示例 1:

输入:chips = [1,2,3]
输出:1
解释:第二个筹码移动到位置三的代价是 1,第一个筹码移动到位置三的代价是 0,总代价为 1。

示例 2:

输入:chips = [2,2,2,3,3]
输出:2
解释:第四和第五个筹码移动到位置二的代价都是 1,所以最小总代价为 2。

解题:

	public int minCostToMoveChips(int[] chips) {
        int ans = Integer.MAX_VALUE;
        for (int i = 0; i < chips.length; i++) {
            int cnt = 0;
            for (int j = 0; j < chips.length; j++) {
                if (j == i) continue;
                int d = Math.abs(chips[j] - chips[i]);
                if (d % 2 == 0) cnt += 0;
                else cnt += 1;
            }
            ans = Math.min(ans, cnt);
        }
        return ans;
    }

5214. 最长定差子序列

给你一个整数数组 arr 和一个整数 difference,请你找出 arr 中所有相邻元素之间的差等于给定 difference 的等差子序列,并返回其中最长的等差子序列的长度。

示例 1:

输入:arr = [1,2,3,4], difference = 1
输出:4
解释:最长的等差子序列是 [1,2,3,4]。

示例 2:

输入:arr = [1,3,5,7], difference = 1
输出:1
解释:最长的等差子序列是任意单个元素。

示例 3:

输入:arr = [1,5,7,8,5,3,4,2,1], difference = -2
输出:4
解释:最长的等差子序列是 [7,5,3,1]。

思路:依次遍历每一个位置,使用HashMap来记录以每个数结尾形成最长等差序列的最大值!
代码:

	public static int longestSubsequence(int[] arr, int difference) {
        Map<Integer, Integer> map = new HashMap<>();
        int ans = 1;
        int cnt = 1;
        for (int t : arr) {
            int pre = t - difference;
            int cur = 1;
            if (map.containsKey(pre)) {
                cur += map.get(pre);
            }
            if (!map.containsKey(t)) {
                map.put(t, cur);
            } else {
                if (map.get(t) < cur) {
                    map.put(t, cur);
                }
            }
            ans = Math.max(ans, cur);
        }
        return ans;
    }

5215. 黄金矿工

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 m * n 的网格 grid 进行了标注。每个单元格中的整数就表示这一单元格中的黄金数量;如果该单元格是空的,那么就是 0。

为了使收益最大化,矿工需要按以下规则来开采黄金:

  • 每当矿工进入一个单元,就会收集该单元格中的所有黄金。
  • 矿工每次可以从当前位置向上下左右四个方向走。
  • 每个单元格只能被开采(进入)一次。
  • 不得开采(进入)黄金数目为 0 的单元格。
  • 矿工可以从网格中 任意一个 有黄金的单元格出发或者是停止。

示例 1:

输入:grid = [[0,6,0],[5,8,7],[0,9,0]]
输出:24
解释:
[[0,6,0],
 [5,8,7],
 [0,9,0]]
一种收集最多黄金的路线是:9 -> 8 -> 7。

示例 2:

输入:grid = [[1,0,7],[2,0,6],[3,4,5],[0,3,0],[9,0,20]]
输出:28
解释:
[[1,0,7],
 [2,0,6],
 [3,4,5],
 [0,3,0],
 [9,0,20]]
一种收集最多黄金的路线是:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7。

思路:dfs
代码:

	int m, n;
    boolean[][] ck;
    int[][] dir = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    int ans = 0;
    public int getMaximumGold(int[][] g) {
        this.m = g.length;
        this.n = g[0].length;
        ck = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (g[i][j] == 0) {
                    continue;
                }
                ck[i][j] = true;
                dfs(g, i, j, g[i][j]);
                ck[i][j] = false;
            }
        }
        return ans;
    }
    public void dfs(int[][] g, int i, int j, int cur) {
        ans = Math.max(ans, cur);
        for (int[] d : dir) {
            int nx = i + d[0], ny = j + d[1];
            if (nx < 0 || nx >= m || ny < 0 || ny >= n || ck[nx][ny] || g[nx][ny] == 0) {
                continue;
            }
            ck[nx][ny] = true;
            dfs(g, nx, ny, cur + g[nx][ny]);
            ck[nx][ny] = false;
        }
    }

你可能感兴趣的:(LeetCode周赛)