第270场力扣周赛

说来惭愧,第一次参加力扣周赛。只ac了前两个题T_T,1965 / 4747。

5942. 找出 3 位偶数

回溯枚举,排除先导0,检查是否是偶数,set去重,最后排序输出。当时写复杂了,可以直接暴搜+Set去重。记录比赛时的回溯code:https://leetcode-cn.com/submissions/detail/245377484/

暴搜+Set:

import java.util.*;

class Solution {
    private boolean check(int[] digits) {
        for (int num : digits) {
            if (num % 2 == 0) {
                return true;
            }
        }
        return false;
    }

    public int[] findEvenNumbers(int[] digits) {
        if (!check(digits)) {
            return new int[]{};
        }
        Set set = new HashSet<>();
        for (int i = 0; i < digits.length; i++) {
            for (int j = 0; j < digits.length; j++) {
                for (int k = 0; k < digits.length; k++) {
                    if (i != j && j != k && i != k && digits[i] != 0) {
                        int num = digits[i] * 100 + digits[j] * 10 + digits[k];
                        if (num % 2 == 0) {
                            set.add(num);
                        }
                    }
                }
            }
        }
        return set.stream().mapToInt(Number::intValue).sorted().toArray();
    }
}

5943. 删除链表的中间节点

一次遍历,让慢指针停在中点⌊n / 2⌋,即待删除节点,同时记录它的前驱节点。由于中点向下取整,fast和slow都从head开始时,n为奇数,slow在中点,fast在尾节点;n为偶数,slow在中点,fast在尾结点.next = null。故while的循环条件cover这两种情况。

class Solution {
    public ListNode deleteMiddle(ListNode head) {
        if (head != null && head.next == null) {
            return null;
        }
        ListNode slow = head, fast = head;
        ListNode pre = new ListNode(-1, head);
        while (fast != null && fast.next != null) {
            slow = slow.next;
            pre = pre.next;
            fast = fast.next.next;
        }
        pre.next = slow.next;
        slow.next = null;
        return head;
    }
}

 5944. 从二叉树一个节点到另一个节点每一步的方向

先从根节点dfs找到起点和终点,同时记录自顶向下的路径,根到起点的路径记为pathS,到终点路径记录为pathD。统计pathS和pathD的公共路径长度i,找到最近公共祖先,即第一个路径不同的位置,用U填入起点到最近公共祖先的路径,为pathS的长度和公共路径长度i的差,拼接pathD。

class Solution {
    String pathS, pathD;

    private void dfs(TreeNode node, int start, int dest, StringBuilder sb) {
        if (node.val == start) {
            pathS = sb.toString();
        }
        if (node.val == dest) {
            pathD = sb.toString();
        }
        if (node.left != null) {
            dfs(node.left, start, dest, sb.append("L"));
            sb.deleteCharAt(sb.length() - 1);
        }
        if (node.right != null) {
            dfs(node.right, start, dest, sb.append("R"));
            sb.deleteCharAt(sb.length() - 1);
        }
    }

    public String getDirections(TreeNode root, int startValue, int destValue) {
        dfs(root, startValue, destValue, new StringBuilder());
        int i = 0;
        // 统计公共路径
        while (i < pathS.length() && i < pathD.length() && pathS.charAt(i) == pathD.charAt(i)) {
            i++;
        }
        // 填入start->最近公共祖先的路径
        StringBuilder sb = new StringBuilder();
        for (int k = 0; k < pathS.length() - i; k++) {
            sb.append("U");
        }
        sb.append(pathD.substring(i));
        return sb.toString();
    }
}

 5932. 合法重新排列数对

有向图欧拉回路/通路输出。

1. 有向图判断欧拉通路存在:图连通,有一个顶点出度大入度1,有一个顶点入度大出度1,其余都是出度=入度。

2. 有向图判断欧拉回路存在:图连通,所有的顶点出度=入度。

即满足重新排列。

首先判断图是哪一种。对于第一种,选择起点开始dfs;对于第二种,任意选择一点开始dfs。

import java.util.*;

class Solution {
    List res;
    Map> adj;
    Map degree;

    private void dfs(int start) {
        if (!adj.containsKey(start)) {
            return;
        }
        while (!adj.get(start).isEmpty()) {
            Integer nei = adj.get(start).poll();
            dfs(nei);
            res.add(new int[]{start, nei});
        }
    }

    public int[][] validArrangement(int[][] pairs) {
        adj = new HashMap<>();
        degree = new HashMap<>();
        res = new ArrayList<>();
        for (int[] p : pairs) {
            Queue tmp = adj.getOrDefault(p[0], new LinkedList<>());
            tmp.add(p[1]);
            adj.put(p[0], tmp);
            degree.put(p[0], degree.getOrDefault(p[0], 0) - 1);
            degree.put(p[1], degree.getOrDefault(p[1], 0) + 1);
        }
        for (Integer key : degree.keySet()) {
            if (degree.get(key) == -1) {
                dfs(key);
            }
        }
        if (res.size() == 0) {
            dfs(pairs[0][0]);
        }
        int[][] ret = new int[res.size()][2];
        int i = res.size() - 1;
        for (int[] p : res) {
            ret[i--] = p;
        }
        return ret;
    }
}

下次周赛加油。 

你可能感兴趣的:(leetcode,算法)