LeetCode第157場周賽

LeetCode第157場周賽

十一出去玩了,沒做周賽,現在有空了補一下
———————————————————————————————————————————————

1217. 玩籌碼

數軸上放置了一些籌碼,每個籌碼的位置存在數組 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。
提示:
1 <= chips.length <= 100 1 <= chips[i] <= 10^9
思路:奇數位置和偶數位置個數更少的就是代價

public int minCostToMoveChips(int[] chips) {
    int cnt = 0;
    for (int i : chips)
        cnt += i % 2;
    return Math.min(cnt, chips.length - cnt);      
}

1218. 最長定差子序列

給你一個整數數組 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]。
提示:
1 <= arr.length <= 10^5
-10^4 <= arr[i], difference <= 10^4
思路:簡單的動態規劃,dp[i] = dp[i - difference] + 1

public int longestSubsequence(int[] arr, int difference) {
    HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
    int res = 0;
    for (int i = 0;i < arr.length;i++) {
        Integer cnt = map.getOrDefault(arr[i] - difference, 0);
        map.put(arr[i], cnt + 1);
        res = Math.max(res, cnt + 1);
    }
    return res;              
}

1219. 黃金礦工 爲了使收益最大化,

礦工需要按以下規則來開採黃金: 每當礦工進入一個單元,就會收集該單元格中的所有黃金。 礦工每次可以從當前位置向上下左右四個方向走。 每個單元格只能被開採(進入)一次。 不得開採(進入)黃金數目爲 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。
提示:
1 <= grid.length, grid[i].length <= 15 0 <= grid[i][j] <= 100 最多 25
個單元格中有黃金。
思路:暴力DFS,一發入魂

int[] dx = {1,-1,0,0};
int[] dy = {0,0,1,-1};
int res = 0;
public void dfs(int[][] grid,int i,int j,boolean[][] flag, int cur) {
    cur += grid[i][j];
    res = Math.max(res, cur);
    flag[i][j] = false;
    for (int d = 0;d < 4;d++) {
        if (i + dx[d] >= 0 && i + dx[d] < grid.length && j + dy[d] >=0 && j + dy[d] < grid[0].length) {
            if (flag[i + dx[d]][j + dy[d]]) {
                flag[i + dx[d]][j + dy[d]] = false;
                dfs(grid, i + dx[d], j + dy[d], flag, cur);
                flag[i + dx[d]][j + dy[d]] = true;
            }					
        }
    }
}
public int getMaximumGold(int[][] grid) {
    boolean[][] flag = new boolean[grid.length][grid[0].length];
    for (int i = 0;i < grid.length;i++) 
        for (int j = 0;j < grid[0].length;j++) 
            flag[i][j] = grid[i][j] > 0 ? true : false;
    for (int i = 0;i < grid.length;i++) {
        for (int j = 0;j < grid[0].length;j++) {
            if (grid[i][j] > 0) {
                flag[i][j] = false;
                dfs(grid, i, j, flag, 0);
                flag[i][j] = true;
            }
        }
    }			
    return res;	
}

1220. 統計元音字母序列的數目

給你一個整數 n,請你幫忙統計一下我們可以按下述規則形成多少個長度爲 n 的字符串:
字符串中的每個字符都應當是小寫元音字母(‘a’, ‘e’, ‘i’, ‘o’, ‘u’) 每個元音 ‘a’ 後面都只能跟着 ‘e’ 每個元音
‘e’ 後面只能跟着 ‘a’ 或者是 ‘i’ 每個元音 ‘i’ 後面 不能 再跟着另一個 ‘i’ 每個元音 ‘o’ 後面只能跟着 ‘i’
或者是 ‘u’ 每個元音 ‘u’ 後面只能跟着 ‘a’ 由於答案可能會很大,所以請你返回 模 10^9 + 7 之後的結果。
示例 1:
輸入:n = 1 輸出:5 解釋:所有可能的字符串分別是:“a”, “e”, “i” , “o” 和 “u”。 示例 2:
輸入:n = 2 輸出:10 解釋:所有可能的字符串分別是:“ae”, “ea”, “ei”, “ia”, “ie”, “io”,
“iu”, “oi”, “ou” 和 “ua”。 示例 3:
輸入:n = 5 輸出:68
提示:
1 <= n <= 2 * 10^4
思路:簡單的動態規劃思想,由於當前字母的來源是確定的,如a只可能來源於e、i、u結尾的字符串,我們只需要每次迭代地將可能的來源所擁有的字符串數目相加之和,賦值給當前字母狀態,最後統計所有可能的狀態之和就可以了。

int mod = 1000000007;
public int countVowelPermutation(int n) {
    if(n == 1) return 5;
    long[][] dp = new long[n + 1][5];
    //a : e
    //e : a i
    //i : a e o u
    //o : i u
    //u : a
    Arrays.fill(dp[1], 1);
    long res = 0;
    for (int i = 2;i <= n;i++) {
        res = 0;
        dp[i][0] = (dp[i - 1][1] + dp[i - 1][2] + dp[i - 1][4]) % mod;
        dp[i][1] = (dp[i - 1][0] + dp[i - 1][2]) % mod;
        dp[i][2] = (dp[i - 1][1] + dp[i - 1][3]) % mod;
        dp[i][3] = dp[i - 1][2] % mod;
        dp[i][4] = (dp[i - 1][2] + dp[i - 1][3]) % mod;
    }
    for (int j = 0;j < 5;j++)
        res = (res + dp[n][j]) % mod;
    return (int)res % mod;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章