• 【刷题】LeetCode刷刷刷 — 2021-05-31(2)


    一、翻转二叉树

    题目描述

    翻转一棵二叉树。
    

    示例

    示例:
    
    输入:
    
         4
       /   
      2     7
     /    / 
    1   3 6   9
    输出:
    
         4
       /   
      7     2
     /    / 
    9   6 3   1
    

    解题

    # Definition for a binary tree node.
    # class TreeNode:
    #     def __init__(self, val=0, left=None, right=None):
    #         self.val = val
    #         self.left = left
    #         self.right = right
    class Solution:
        def invertTree(self, root: TreeNode) -> TreeNode:
            if not root:
                return None
            
            temp = root.left
            root.left =  root.right
            root.right = temp
    
            self.invertTree(root.left)
            self.invertTree(root.right)
            return root
    

    典型二叉树反转,使用递归。

    利用一个临时结点,使左右结点进行交换。

    交换动作完成后,开始递归,左右两边的子树。

    二、三个数的最大乘积

    题目描述

    给你一个整型数组 nums ,在数组中找出由三个数组成的最大乘积,并输出这个乘积。
    

    示例

    示例 1:
    
    输入:nums = [1,2,3]
    输出:6
    示例 2:
    
    输入:nums = [1,2,3,4]
    输出:24
    示例 3:
    
    输入:nums = [-1,-2,-3]
    输出:-6
    

    解题

    class Solution:
        def maximumProduct(self, nums: List[int]) -> int:
            nums.sort()
            max1 = nums[-1]* nums[-2]* nums[-3]
            max2 = nums[0]* nums[1]* nums[-1]
            return max(max1, max2)
    

    如果是一个无序的数组,处理起来没那么快。可以先将数组排序,从小到大。这样一来,3个数的最大乘积
    要考虑这几种情况:

    • 数组里都是正数,那么3个数最大乘积就是后3位相乘。
    • 数组里都是负数,那么3个数最大乘积就是后3位相乘。
    • 数组里有正有负,那么3个数最大乘积可能:1.只有1个负数时,仍然为最后3个相乘。2. 大于等于2个负数时,就是最小的2个负数与最大的正数相乘。

    所以,总结下来就是2种情况,把两种都计算一遍,然后比较哪个大返回谁。

    三、删除有序数组中的重复项

    题目描述

    给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
    
    不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
    

    示例

    示例 1:
    
    输入:nums = [1,1,2]
    输出:2, nums = [1,2]
    解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。
    不需要考虑数组中超出新长度后面的元素。
    示例 2:
    
    输入:nums = [0,0,1,1,1,2,2,3,3,4]
    输出:5, nums = [0,1,2,3,4]
    解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。
    不需要考虑数组中超出新长度后面的元素。
    

    解题

    class Solution:
        def removeDuplicates(self, nums: List[int]) -> int:
            fast = 1
            slow = 1
            for fast in range(1, len(nums)):
                if nums[fast] != nums[fast-1]:
                    nums[slow] = nums[fast]
                    slow += 1
                fast += 1
            return slow
    

    题目重点是要原地删除,用双指针解决,分别是fastslow,初始都指在下标为1的元素。

    • fast为遍历的指针,每遍历一个元素,比较fast与前一个 即fast-1是否相等。
    • 如果不相等,就可以把fast所在的元素,与slow交换,放到前面去。然后slow+=1,指向下一个元素插入
      的位置。
    • 如果相等,说明fast与前一个重复,fast+=1,继续往右遍历,直到下一个不一样的元素,继续放到slow位置。

    四、删除排序链表中的重复元素

    题目描述

    存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 。
    
    返回同样按升序排列的结果链表。
    

    示例

    示例 1:
    输入:head = [1,1,2]
    输出:[1,2]
    

    示例 2:
    输入:head = [1,1,2,3,3]
    输出:[1,2,3]
    

    解题

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def deleteDuplicates(self, head: ListNode) -> ListNode:
            if not head:
                return head
            cur = head
            while cur.next:
                if cur.val == cur.next.val:
                    cur.next = cur.next.next
                else:
                    cur = cur.next
            return head
    

    这里是一个升序链表,所以重复的数据是连续排列的。这样,可以一次遍历解决。

    • cur指针指向head结点,开始往下遍历。这里先判断下if not head的情况。
    • 如果cur的值cur.val,与下一个结点的值cur.next.val相等,说明重复,要删除cur.next
      不过这里的删除操作是改变指针指向,cur.next指向cur.next.next即可。被绕开的结点没有引用,会
      被自动回收。
    • 如果不等于,说明不重复,cur = cur.nextcur指针继续往右移动。

    五、链表的中间结点

    题目描述

    给定一个头结点为 head 的非空单链表,返回链表的中间结点。

    如果有两个中间结点,则返回第二个中间结点。

    示例

    示例 1:
    
    输入:[1,2,3,4,5]
    输出:此列表中的结点 3 (序列化形式:[3,4,5])
    返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
    注意,我们返回了一个 ListNode 类型的对象 ans,这样:
    ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
    示例 2:
    
    输入:[1,2,3,4,5,6]
    输出:此列表中的结点 4 (序列化形式:[4,5,6])
    由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
    

    解题

    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def middleNode(self, head: ListNode) -> ListNode:
            n = 0
            cur = head
            while cur:
                n += 1
                cur = cur.next
            
            m = 0
            cur = head
            while m < n // 2:
                m += 1
                cur = cur.next
            return cur
    

    两次遍历。

    • 第一次遍历,知道了链表的长度n
    • 第二次遍历,只遍历到n的一半 while m < n // 2,返回指针cur
    --不要用肉体的勤奋,去掩盖思考的懒惰--
  • 相关阅读:
    XCNA进阶测试20220330
    MobaXterm
    thinkpad
    华为NQA实验
    M1芯片 使用pod install 报错You may have encountered a bug in the Ruby interpreter or extension libraries. Bug reports are welcome. For details: https://www.rubylang.org/bugreport.html
    provider 跨组件状态管理
    2022年华北电力大学计算机系考研上岸同学初试经验...
    flaskrestful响应处理
    typeScript枚举
    Object.asign
  • 原文地址:https://www.cnblogs.com/pingguo-softwaretesting/p/14830970.html
Copyright © 2020-2023  润新知