【2022.12.19】备战春招Day14——每日一题 + 234. 回文链表 + 860. 柠檬水找零

【每日一题】1971. 寻找图中是否存在路径

有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n -1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] = [ui, vi] 表示顶点 ui 和顶点 vi之间的双向边。 每个顶点对由 最多一条 边连接,并且没有顶点存在与自身相连的边。

请你确定是否存在从顶点 source 开始,到顶点 destination 结束的 有效路径 。

给你数组 edges 和整数 n、source 和 destination,如果从 source 到 destination 存在 有效路径,则返回 true,否则返回 false 。

在这里插入图片描述
输入:n = 3, edges = [[0,1],[1,2],[2,0]], source = 0, destination = 2
输出:true
解释:存在由顶点 0 到顶点 2 的路径:

  • 0 → 1 → 2
  • 0 → 2
题目解析

【广度优先搜索】:从顶点出发,找到该点所能到达的其他顶点,并存入到队列中。之后每次从队列中取出队头顶点,将该点所能到达的其他顶点压入到队列中。

class Solution {
    public boolean validPath(int n, int[][] edges, int source, int destination) {
        if(source == destination) return true;
        // 使用邻接表存储
        Map<Integer, List<Integer>> map = new HashMap<>();
        for(int[] e : edges){
            List<Integer> list = map.getOrDefault(e[0], new ArrayList<>());
            list.add(e[1]);
            map.put(e[0], list);

            list = map.getOrDefault(e[1], new ArrayList<>());
            list.add(e[0]);
            map.put(e[1], list);
        }
        // 广度优先
        Deque<Integer> queue = new LinkedList<>();
        boolean[] flag = new boolean[n];
        //顶点
        flag[source] = true;
        if(map.get(source) == null) return false;
        for(Integer i : map.get(source)){
            queue.addLast(i);
            flag[i] = true;
        }
        while(!queue.isEmpty()){
            int node = queue.removeFirst();
            if(node == destination) return true;
            if(map.get(node) == null) continue;
            for(Integer i : map.get(node)){
                if(flag[i]) continue;
                queue.addLast(i);
                flag[i] = true;
            }
        }
        return false;
    }
}

【深度优先搜索】:使用递归,每遇到一个顶点,一直向下搜索。

class Solution {
    boolean[] flag;
    public boolean validPath(int n, int[][] edges, int source, int destination) {
        if(source == destination) return true;
        flag = new boolean[n];
        // 使用邻接表存储
        Map<Integer, List<Integer>> map = new HashMap<>();
        for(int[] e : edges){
            List<Integer> list = map.getOrDefault(e[0], new ArrayList<>());
            list.add(e[1]);
            map.put(e[0], list);

            list = map.getOrDefault(e[1], new ArrayList<>());
            list.add(e[0]);
            map.put(e[1], list);
        }
       // 递归
       return dfs(map, source, destination);

    }

    public boolean dfs(Map<Integer, List<Integer>> map, int source, int destination){
        if(source == destination) return true;
        if(map.get(source) == null) return false;
        for(Integer i : map.get(source)){
            if(flag[i]) continue;
            flag[i] = true;
            if(dfs(map, i, destination)) return true;
        }
        return false;
    }
}

【并查集】

class Solution {
    // 并查集模版!
    class UnionFind {
        private int[] parent;

        public UnionFind(int n) {
            parent = new int[n];
            for (int i = 0; i < n; i++) {
                parent[i] = i;
            }
        }

        public int find(int x) {
            if (x != parent[x]) {
                parent[x] = find(parent[x]);
            }
            return parent[x];
        }

        public void union(int x, int y) {
            parent[find(x)] = parent[find(y)];
        }
    }

    public boolean validPath(int n, int[][] edges, int source, int destination) {
         UnionFind uf = new UnionFind(n);
         // 一条边的两个点 属于一个集合
        for (int[] edge : edges) {
            uf.union(edge[0], edge[1]);
        }
        return uf.find(source) == uf.find(destination);
    }
}
【leetcode hot 100】739. 每日温度
题目描述

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

题目描述

【单调栈】:该题可以使用单调栈。从后向前遍历,栈从上到下存放温度递增的顺序。
【入栈】:将当前温度压入栈
【出栈】:如果栈顶温度小于当前温度,则将栈顶出栈。

class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        // 单调栈
        // 栈中存放的是 温度递增的顺序
        Deque<Integer> stack = new LinkedList<>();
        int[] re = new int[temperatures.length];
        stack.push(temperatures.length - 1);
        for(int i = temperatures.length - 2; i >= 0; i--){
            while(!stack.isEmpty() && temperatures[stack.peek()] <= temperatures[i]){
                stack.pop();
            }
            if(stack.isEmpty()){
                re[i] = 0;
            }else{
                re[i] = stack.peek() - i;
            }
            stack.push(i);
        }
        return re;
    }
}
【代码随想录】 860. 柠檬水找零
题目描述

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

输入:bills = [5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。

题目解析
class Solution {
    public boolean lemonadeChange(int[] bills) {
        int[] b = new int[3];
        for(int i : bills){
            if(i == 5){
                b[0]++;
            }else if(i == 10){
                if(b[0] > 0){
                    b[0]--;
                    b[1]++;
                }else{
                    return false;
                }
            }else{
                if(b[1] > 0 && b[0] > 0){
                    b[0]--;
                    b[1]--;
                }else if(b[0] >= 3){
                    b[0] -= 3;
                }else{
                    return false;
                }
            }
        }
        return true;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值