刷题LeetCode刷刷刷 — 2021-05-31

Posted 把苹果咬哭

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了刷题LeetCode刷刷刷 — 2021-05-31相关的知识,希望对你有一定的参考价值。

一、翻转二叉树

题目描述

翻转一棵二叉树。

示例

示例:

输入:

     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

以上是关于刷题LeetCode刷刷刷 — 2021-05-31的主要内容,如果未能解决你的问题,请参考以下文章

刷题LeetCode刷刷刷 — 2021-06-01

刷题LeetCode刷刷刷 — 2021-05-30

每日刷题191117

每日刷题191124

每日刷题1118

每日刷题191122