zoukankan      html  css  js  c++  java
  • [Leetcode Weekly Contest]270

    链接:LeetCode

    [Leetcode]2094. 找出 3 位偶数

    给你一个整数数组 digits ,其中每个元素是一个数字(0 - 9)。数组中可能存在重复元素。
    你需要找出 所有 满足下述条件且 互不相同 的整数:

    • 该整数由 digits 中的三个元素按 任意 顺序 依次连接 组成。
    • 该整数不含 前导零
    • 该整数是一个 偶数

    例如,给定的 digits 是 [1, 2, 3] ,整数 132 和 312 满足上面列出的全部条件。
    将找出的所有互不相同的整数按 递增顺序 排列,并以数组形式返回。

    遍历即可。

    class Solution {
        public int[] findEvenNumbers(int[] digits) {
            Set<Integer> resSet = new HashSet<>();
            for(int i=0;i<digits.length;++i) {
                int res1 = digits[i];
                if(res1 == 0) continue;
                for(int j=0;j<digits.length;++j) {
                    if(j==i) continue;
                    int res2 = res1*10+digits[j];
                    for(int k=0;k<digits.length;++k) {
                        if(k==i || k==j || (digits[k]&1)!=0) continue;
                        resSet.add(res2*10+digits[k]);
                    }
                }
            }
            int[] res = new int[resSet.size()];
            int i = 0;
            for(int result:resSet) {
                res[i++] = result;
            }
            Arrays.sort(res);
            return res;
        }
    }
    

    [Leetcode]2095. 删除链表的中间节点

    给你一个链表的头节点 head 。删除 链表的 中间节点 ,并返回修改后的链表的头节点 head 。
    长度为 n 链表的中间节点是从头数起第 ⌊n / 2⌋ 个节点(下标从 0 开始),其中 ⌊x⌋ 表示小于或等于 x 的最大整数。
    对于 n = 1、2、3、4 和 5 的情况,中间节点的下标分别是 0、1、1、2 和 2 。

    快慢指针,注意分情况讨论即可。

    class Solution {
        public ListNode deleteMiddle(ListNode head) {
            if(head.next==null) return null;
            ListNode dummy = head, pre=head, first=head, second =head;
            for(;;) {
                if(first.next==null) {
                    pre.next = pre.next.next;
                    break;
                }
                if(first.next.next == null ) {
                    second.next = second.next.next;
                    break;
                }
                pre = second;
                second = second.next;
                first = first.next.next;
            }
            return dummy;
        }
    }
    

    [Leetcode]2096. 从二叉树一个节点到另一个节点每一步的方向

    给你一棵 二叉树 的根节点 root ,这棵二叉树总共有 n 个节点。每个节点的值为 1 到 n 中的一个整数,且互不相同。给你一个整数 startValue ,表示起点节点 s 的值,和另一个不同的整数 destValue ,表示终点节点 t 的值。

    请找到从节点 s 到节点 t 的 最短路径 ,并以字符串的形式返回每一步的方向。每一步用 大写 字母 'L' ,'R' 和 'U' 分别表示一种方向:

    'L' 表示从一个节点前往它的 左孩子 节点。
    'R' 表示从一个节点前往它的 右孩子 节点。
    'U' 表示从一个节点前往它的 父 节点。
    请你返回从 s 到 t 最短路径 每一步的方向。

    深度优先搜索,难度在于如何在\(O(N)\)时空复杂度下寻找根节点到特定节点的路径。在传统的DFS算法中,我们会把路径传入参数,遍历搜索,其时空复杂度为\(O(N^2)\)
    因此,我们需要尝试从节点向上遍历直到根节点从而得到对应的路径,并反向得出目标字符串。但对于一般的二叉树数据结构,我们无法很快地得到某一个节点的父节点,因此我们需要通过深度优先搜索,利用哈希表额外维护每个节点对应的父节点。维护父节点哈希表后,我们便可以在 \(O(N)\)的时间与空间复杂度内求出根节点到特定节点的路径。在求出根节点分别到两个节点的路径后,两个节点之间的路径也就容易求了。

    /**
     * Definition for a binary tree node.
     * public class TreeNode {
     *     int val;
     *     TreeNode left;
     *     TreeNode right;
     *     TreeNode() {}
     *     TreeNode(int val) { this.val = val; }
     *     TreeNode(int val, TreeNode left, TreeNode right) {
     *         this.val = val;
     *         this.left = left;
     *         this.right = right;
     *     }
     * }
     */
    class Solution {
        Map<TreeNode, TreeNode> parentMap = new HashMap<>();
        public String getDirections(TreeNode root, int startValue, int destValue) {
            TreeNode node1 = findNode(root, startValue);
            TreeNode node2 = findNode(root, destValue);
            TreeNode head = lowestCommonAncestor(root, node1, node2);
            StringBuffer path1 = new StringBuffer();
            StringBuffer path2 = new StringBuffer();
            TreeNode node = node1;
            while (node != head) {
                path1.append('U');
                node = parentMap.get(node);
            }
            node = node2;
            while (node != head) {
                TreeNode parent = parentMap.get(node);
                if (node == parent.left) {
                    path2.append('L');
                } else {
                    path2.append('R');
                }
                node = parent;
            }
            path2.reverse();
            StringBuffer directions = new StringBuffer();
            directions.append(path1);
            directions.append(path2);
            return directions.toString();
        }
    
        /**
         * 查找二叉树中值为val的节点,并将查找过程中的(节点,其父节点)存到map
         */
        public TreeNode findNode(TreeNode node, int val) {
            if (node == null) {
                return null;
            }
            if (node.val == val) {
                return node;
            }
            TreeNode node1 = findNode(node.left, val);
            if (node1 != null) {
                parentMap.put(node.left, node);
                return node1;
            }
            TreeNode node2 = findNode(node.right, val);
            if (node2 != null) {
                parentMap.put(node.right, node);
                return node2;
            }
            return null;
        }
    
        /**
         * 查找p和q两个节点的最近祖先节点
         */
        public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
            if (root == p || root == q) {
                return root;
            }
            if (root != null) {
                TreeNode lNode = lowestCommonAncestor(root.left, p, q);
                TreeNode rNode = lowestCommonAncestor(root.right, p, q);
                if (lNode != null && rNode != null) {
                    return root;
                } else if (lNode == null) {
                    return rNode;
                } else {
                    return lNode;
                }
            }
            return null;
        }
    }
    

    [Leetcode]2097. 合法重新排列数对

    给你一个下标从 0 开始的二维整数数组 pairs ,其中 pairs[i] = [starti, endi] 。如果 pairs 的一个重新排列,满足对每一个下标 i ( 1 <= i < pairs.length )都有 endi-1 == starti ,那么我们就认为这个重新排列是 pairs 的一个 合法重新排列 。
    请你返回 任意一个 pairs 的合法重新排列。
    注意:数据保证至少存在一个 pairs 的合法重新排列。

    有向图的欧拉通路。求解欧拉通路可以使用深度优先搜索,我们一般使用 \(\text{Hierholzer}\) 算法求解欧拉通路.对于本题而言,我们首先需要找到欧拉通路的起始节点:如果图中所有节点的入度和出度都相等,那么从任意节点开始都存在欧拉通路;如果图中存在一个节点的出度比入度恰好多 1,另一个节点的入度恰好比出度多 1,那么欧拉通路必须从前一个节点开始,到后一个节点结束。除此之外的有向图都不存在欧拉通路,本体保证了至少存在一个合法排列,因此图已经是上述的两种情况之一。

    class Solution {
        LinkedList<Integer> ret = new LinkedList<>();
        HashMap<Integer, LinkedList<Integer>> map = new HashMap<>();
        HashMap<Integer, Integer> inDegree = new HashMap<>();
        public int[][] validArrangement(int[][] pairs) {
            for (int[] pair : pairs) {
                int out = pair[0], in = pair[1];
                inDegree.put(in, inDegree.getOrDefault(in, 0) + 1);
                LinkedList<Integer> list = map.getOrDefault(out, new LinkedList<>());
                list.add(in);
                map.put(out, list);
            }
            int start = pairs[0][0];
            for (Map.Entry<Integer, LinkedList<Integer>> entry : map.entrySet()) {
                //out list
                LinkedList<Integer> outList = entry.getValue();
                Integer key = entry.getKey();
                Integer inValue = inDegree.getOrDefault(key, 0 );
                if(inValue + 1 == outList.size()){
                    start = key;
                    break;
                }
            }
            dfs(start);
            int n = pairs.length;
            int[][] ans = new int[n][2];
            for(int i = 0; i < n; i++){
                ans[i][0] = ret.pollLast();
                ans[i][1] = ret.peekLast();
            }
            return ans;
        }
        void dfs(int start){
            LinkedList<Integer> list = map.get(start);
            while(list != null && !list.isEmpty()){
                Integer next = list.pollLast();
                dfs(next);
            }
            ret.add(start);
        }
    }
    

    Leetcode

  • 相关阅读:
    mysql 新用户添加和权限
    分治法
    插入排序
    猴子分桃问题
    关于PHP面向对象 静态方法的疑问
    php中static 静态变量和普通变量的区别
    php函数引用返回
    redis 限制请求次数的写法
    cas单点登录认证原理
    聚簇索引和非聚簇索引
  • 原文地址:https://www.cnblogs.com/hellojamest/p/15664699.html
Copyright © 2011-2022 走看看