LeetCode 1219. 黄金矿工 / 1748. 唯一元素的和 / 1405. 最长快乐字符串

这是一系列关于算法解题的概述,包括寻找最大黄金路径、唯一元素求和以及构建快乐字符串的问题。通过回溯法解决黄金矿工问题,找到路径最大黄金数;计算整数数组中唯一元素的总和;以及在限制条件下构建最长的快乐字符串。
摘要由CSDN通过智能技术生成

1219. 黄金矿工

2022.2.5 每日一题

题目描述

你要开发一座金矿,地质勘测学家已经探明了这座金矿中的资源分布,并用大小为 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。

提示:

1 <= grid.length, grid[i].length <= 15
0 <= grid[i][j] <= 100
最多 25 个单元格中有黄金。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/path-with-maximum-gold
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

回溯

class Solution {
    int[][] dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    int[][] grid;
    int m;
    int n;
    public int getMaximumGold(int[][] grid) {
        //格子比较少,且黄金比较少,所以就回溯应该可以
        this.grid = grid;
        m = grid.length;
        n = grid[0].length;
        int res = 0;
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(grid[i][j] == 0)
                    continue;
                boolean[][] used = new boolean[m][n];
                used[i][j] = true;
                int t = find(used, i, j, grid[i][j]);
                res = Math.max(res, t);
                used[i][j] = false;
            }
        }    
        return res;
    }

    public int find(boolean[][] used, int i, int j, int gold){

        int res = gold;
        for(int[] d : dir){
            int x = i + d[0];
            int y = j + d[1];
            if(x >= 0 && y >= 0 && x < m && y < n && !used[x][y] && grid[x][y] != 0){
                used[x][y] = true;
                res = Math.max(res, find(used, x, y, gold + grid[x][y]));
                used[x][y] = false;
            }
        }
        return res;
    }
}

1748. 唯一元素的和

2022.2.6 每日一题

题目描述

给你一个整数数组 nums 。数组中唯一元素是那些只出现 恰好一次 的元素。

请你返回 nums 中唯一元素的 和 。

示例 1:

输入:nums = [1,2,3,2]
输出:4
解释:唯一元素为 [1,3] ,和为 4 。

示例 2:

输入:nums = [1,1,1,1,1]
输出:0
解释:没有唯一元素,和为 0 。

示例 3 :

输入:nums = [1,2,3,4,5]
输出:15
解释:唯一元素为 [1,2,3,4,5] ,和为 15 。

提示:

1 <= nums.length <= 100
1 <= nums[i] <= 100

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sum-of-unique-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

class Solution {
    public int sumOfUnique(int[] nums) {
        int[] count = new int[101];
        for(int i = 0; i < nums.length; i++){
            count[nums[i]]++;
        }
        int res = 0;
        for(int i = 0; i < 101; i++){
            if(count[i] == 1)
                res += i;
        }
        return res;
    }
}

1405. 最长快乐字符串

2022.2.7 每日一题,开工大吉

题目描述

如果字符串中不含有任何 ‘aaa’,‘bbb’ 或 ‘ccc’ 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。

给你三个整数 a,b ,c,请你返回 任意一个 满足下列全部条件的字符串 s:

s 是一个尽可能长的快乐字符串。
s 中 最多 有a 个字母 ‘a’、b 个字母 ‘b’、c 个字母 ‘c’ 。
s 中只含有 ‘a’、‘b’ 、‘c’ 三种字母。

如果不存在这样的字符串 s ,请返回一个空字符串 “”。

示例 1:

输入:a = 1, b = 1, c = 7
输出:“ccaccbcc”
解释:“ccbccacc” 也是一种正确答案。

示例 2:

输入:a = 2, b = 2, c = 1
输出:“aabbc”

示例 3:

输入:a = 7, b = 1, c = 0
输出:“aabaa”
解释:这是该测试用例的唯一正确答案。

提示:

0 <= a, b, c <= 100
a + b + c > 0

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-happy-string
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

思路其实很简单,因为不能连续放三个,所以最多连续放两个
那么该怎么摆放呢
我们能想到的最简单的情况就是如果三个字母相同的话,一个一个放就可以了,所以我们想到的目标就是使三个字母个数相同
如果两个字母数目相同且大于第三个字母的个数呢,两个相同的字母一个一个放,那么就会和第三个字母个数相同
那如果三个字母个数都不相同,那么最多的放两个,次多的放一个,这样就会向第二种情况靠近

我写的比较复杂,因为想不到简单的写法,需要注意各种空指针的情况

class Solution {
    public String longestDiverseString(int a, int b, int c) {
        //怎么摆放比较合适呢,应该是三个字母个数差不多相同
        //那么按这样来的话,摆放的策略就是先摆放最多的字母,
        //然后摆放第二多的,如果两个字母相同了,那么就一直放两个,直到和第三个相同
        //然后三个轮流摆放

        StringBuffer sb = new StringBuffer();

        PriorityQueue<int[]> pq = new PriorityQueue<>((x, y) -> (y[1] - x[1]));
        if(a != 0)
            pq.offer(new int[]{1, a});
        if(b != 0)
            pq.offer(new int[]{2, b});
        if(c != 0)
            pq.offer(new int[]{3, c});
        while(!pq.isEmpty()){
            int t = helper(pq);
            if(t == 1){
                int[] first = pq.poll();
                sb.append((char)(first[0] - 1 + 'a'));
                if(first[1] - 1 > 0)
                    sb.append((char)(first[0] - 1 + 'a'));
                if(pq.isEmpty())
                    return sb.toString();
                int[] second = pq.poll();
                sb.append((char)(second[0] - 1 + 'a'));
                if(first[1] - 2 > 0)
                    pq.offer(new int[]{first[0], first[1] - 2});
                if(second[1] - 1 > 0) 
                    pq.offer(new int[]{second[0], second[1] - 1});
            }else if(t == 2){
                int[] first = pq.poll();
                int[] second = pq.poll();
                sb.append((char)(first[0] - 1 + 'a'));
                sb.append((char)(second[0] - 1 + 'a'));
                if(first[1] - 1 > 0)
                    pq.offer(new int[]{first[0], first[1] - 1});
                if(second[1] - 1 > 0) 
                    pq.offer(new int[]{second[0], second[1] - 1});
            }else{
                int[] first = pq.poll();
                int[] second = pq.poll();
                int[] third = pq.poll();
                int num = first[1];
                while(num-- > 0){
                    sb.append((char)(first[0] - 1 + 'a'));
                    sb.append((char)(second[0] - 1 + 'a'));
                    sb.append((char)(third[0] - 1 + 'a'));
                }
                return sb.toString();
            }
        }
        return sb.toString();
    }

    //如果最大的比第二大的大,那么就返回1
    //如果前两个相同,比第三个大,返回2
    //如果三个相同,返回3
    public int helper(PriorityQueue<int[]> pq){
        if(pq.size() == 1)
            return 1;
        int[] first = pq.poll();
        int[] second = pq.poll();
        int[] third = pq.peek();
        int flag = 0;
        if(first[1] > second[1])
            flag = 1;
        else if(third == null || second[1] > third[1])
            flag = 2;
        else
            flag = 3;
        pq.offer(first);
        pq.offer(second);
        return flag;
    }
}

其实按照构建的字符串,判断是否三个字符相连,如果有三个相同字符相连,那么就用第二多的,这样写简单点

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值