zoukankan      html  css  js  c++  java
  • 第十周LeetCode记录

    11.18 46. 拼接最大数

    给定长度分别为 m 和 n 的两个数组,其元素由 0-9 构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n) 个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。

    求满足该条件的最大数。结果返回一个表示该最大数的长度为 k 的数组。

    输入:
    nums1 = [3, 4, 6, 5]
    nums2 = [9, 1, 2, 5, 8, 3]
    k = 5
    输出:
    [9, 8, 6, 5, 3]
    
    输入:
    nums1 = [6, 7]
    nums2 = [6, 0, 4]
    k = 5
    输出:
    [6, 7, 6, 0, 4]
    

    最优解

    class Solution:
        def maxNumber(self, nums1, nums2, k):
    
            def pick_max(nums, k):
                stack = []
                drop = len(nums) - k
                for num in nums:
                    while drop and stack and stack[-1] < num:
                        stack.pop()
                        drop -= 1
                    stack.append(num)
                return stack[:k]
    
            def merge(A, B):
                ans = []
                while A or B:
                    bigger = A if A > B else B
                    ans.append(bigger[0])
                    bigger.pop(0)
                return ans
    
            return max(merge(pick_max(nums1, i), pick_max(nums2, k-i)) for i in range(k+1) if i <= len(nums1) and k-i <= len(nums2))
    

    总结

    从2个数组共取k个数字,遍历各种情况。分治解决

    pick_max是从nums数组里取前k位组成新的数组,merge是将两数组合并为最大数组

    思考一下时间复杂度和空间复杂度是多少

    11.19 47. 不同字符的最小子序列

    返回字符串 text 中按字典序排列最小的子序列,该子序列包含 text 中所有不同字符一次。

    输入:"cdadabcc"
    输出:"adbc"
    
    输入:"abcd"
    输出:"abcd"
    
    输入:"ecbacba"
    输出:"eacb"
    
    输入:"leetcode"
    输出:"letcod"
    

    思路

    跟上面的题型一样,利用栈来解

    我的解

    class Solution:
        def smallestSubsequence(self, s: str) -> str:
            from collections import Counter
            s_dic = Counter(s)
            stack = []
            for i in s:
                if i not in stack:
                    while stack and stack[-1] >= i and s_dic[stack[-1]] > 0:
                        stack.pop()
                    stack.append(i)
                s_dic[i] -= 1
    
            return ''.join(stack)
    

    11.20 48. 对称的二叉树

    请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。

    例如,二叉树 [1,2,2,3,4,4,3] 是对称的。

        1
       / 
      2   2
     /  / 
    3  4 4  3
    

    但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:

        1
       / 
      2   2
          
       3    3
    

    最优解

    class Solution:
        @classmethod
        def isSymmetric(self, root: TreeNode) -> bool:
            
            def recrue(Left,Right):
                if not Left and not Right:
                    return True
                
                if not Left or not Right or Left.val != Right.val:
                    return False
    
                return recrue(Left.left,Right.right) and recrue(Left.right,Right.left)
    
            return recrue(root.left,root.right) if root else True
    

    总结

    和29题 另一个树的子树同样的方法,递归遍历对称树的定义即可。

    11.21 49.最接近原点的k个点

    我们有一个由平面上的点组成的列表 points。需要从中找出 K 个距离原点 (0, 0) 最近的点。

    (这里,平面上两点之间的距离是欧几里德距离。)

    你可以按任何顺序返回答案。除了点坐标的顺序之外,答案确保是唯一的。

    输入:points = [[1,3],[-2,2]], K = 1
    输出:[[-2,2]]
    解释: 
    (1, 3) 和原点之间的距离为 sqrt(10),
    (-2, 2) 和原点之间的距离为 sqrt(8),
    由于 sqrt(8) < sqrt(10),(-2, 2) 离原点更近。
    我们只需要距离原点最近的 K = 1 个点,所以答案就是 [[-2,2]]。
    
    输入:points = [[3,3],[5,-1],[-2,4]], K = 2
    输出:[[3,3],[-2,4]]
    (答案 [[-2,4],[3,3]] 也会被接受。)
    

    思路

    遍历每个点,排序取前k。

    我的解

    class Solution:
        def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]:
            import math
            def calc_dis(point):
                x, y = point
                return math.sqrt(x ** 2 + y ** 2)
    
            return sorted(points,key=lambda k:calc_dis(k))[:K]
    

    最优解

    优先队列

    我们可以使用一个优先队列(大根堆)实时维护前 KK 个最小的距离平方。

    首先我们将前 KK 个点的编号(为了方便最后直接得到答案)以及对应的距离平方放入优先队列中,随后从第 K+1K+1 个点开始遍历:如果当前点的距离平方比堆顶的点的距离平方要小,就把堆顶的点弹出,再插入当前的点。当遍历完成后,所有在优先队列中的点就是前 KK 个距离最小的点。

    class Solution:
        def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]:
            q = [(-x ** 2 - y ** 2, i) for i, (x, y) in enumerate(points[:K])]
            heapq.heapify(q)
            
            n = len(points)
            for i in range(K, n):
                x, y = points[i]
                dist = -x ** 2 - y ** 2
                heapq.heappushpop(q, (dist, i))
            
            ans = [points[identity] for (_, identity) in q]
            return ans
    
    

    总结

    取前几个后几个的题型,优先想到用堆处理。

    11.23 50. 最大二叉树

    给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:

    二叉树的根是数组中的最大元素。
    左子树是通过数组中最大值左边部分构造出的最大二叉树。
    右子树是通过数组中最大值右边部分构造出的最大二叉树。
    通过给定的数组构建最大二叉树,并且输出这个树的根节点。

    输入:[3,2,1,6,0,5]
    输出:返回下面这棵树的根节点:
    
          6
        /   
       3     5
            / 
         2  0   
           
            1
    
    

    最优解

    public class Solution {
        public TreeNode constructMaximumBinaryTree(int[] nums) {
            return construct(nums, 0, nums.length);
        }
        public TreeNode construct(int[] nums, int l, int r) {
            if (l == r)
                return null;
            int max_i = max(nums, l, r);
            TreeNode root = new TreeNode(nums[max_i]);
            root.left = construct(nums, l, max_i);
            root.right = construct(nums, max_i + 1, r);
            return root;
        }
        public int max(int[] nums, int l, int r) {
            int max_i = l;
            for (int i = l; i < r; i++) {
                if (nums[max_i] < nums[i])
                    max_i = i;
            }
            return max_i;
        }
    }
    

    总结

    递归处理。每次处理最左最右最大。

  • 相关阅读:
    遍历文件夹及子文件夹_函数
    wbadmin与vssadmin
    WSB备份到远程共享文件夹的限制
    Linux 性能工具集
    shell 与 空格
    Git 仓库结构 (二)***
    Linux下scp的用法***
    FINDSTR 命令使用详解
    Git 的origin和master分析 ***
    Git push *****
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/14052190.html
Copyright © 2011-2022 走看看