美文网首页
LeetCode刷题之《错题集》

LeetCode刷题之《错题集》

作者: ShowMeCoding | 来源:发表于2021-09-05 10:56 被阅读0次
    剑指Offer11-旋转数组的最小数字

    输入:[3,4,5,1,2]
    输出:1

    class Solution:
        def minArray(self, numbers: List[int]) -> int:
            # 方法1:无论如何旋转,最小值不变
            return min(numbers)
    
            # 方法2:顺序查找,找到最小值
            minNum = numbers[0]
            for i in range(1, len(numbers)):
                if numbers[i] < minNum:
                    minNum = numbers[i]
            return minNum
    
            # 方法3:二分查找
            low = 0
            high = len(numbers) - 1
            while low < high:
                mid = low + (high-low)//2
                if numbers[mid] < numbers[high]:
                    high = mid
                elif numbers[mid] > numbers[high]:
                    low = mid + 1
                else:
                    high -= 1
            return numbers[low]
    
    189-旋转数组

    输入: nums = [1,2,3,4,5,6,7], k = 3
    输出: [5,6,7,1,2,3,4]
    解释:
    向右旋转 1 步: [7,1,2,3,4,5,6]
    向右旋转 2 步: [6,7,1,2,3,4,5]
    向右旋转 3 步: [5,6,7,1,2,3,4]

    • 方法1:使用辅助数组
    class Solution:
        def rotate(self, nums: List[int], k: int) -> None:
            """
            Do not return anything, modify nums in-place instead.
            """
            # 方法1
            res = []
            length = len(nums)
            key = length - (k % length)    # 关键取余数操作
            for i in range(key,length,1):
                res.append(nums[i])
            for j in range(key):
                res.append(nums[j])
            nums[:] = res
    
            # 方法2
            res = []
            length = len(nums)
            key = length - (k % length) 
            res = nums[key:] + nums[:key]
            nums[:] = res
    
    • 方法2:原地交换
    
    
    剑指Offer53-在排序数组中查找数字

    输入: nums = [5,7,7,8,8,10], target = 8
    输出: 2
    解释: 8在排序数组中出现了2次

    class Solution:
        def search(self, nums: List[int], target: int) -> int:
            # 方法1:顺序查找
            # res = 0
            # for num in nums:
            #     if num == target:
            #         res += 1
            # return res
    
            # 方法2:二分查找
            # 1 搜索右边界,右边界的左侧都是 <= target 的数
            left = 0
            right = len(nums) - 1
            while left <= right:
                mid = left + (right-left)//2
                if nums[mid] > target:
                    right = mid - 1
                else:
                    left = mid + 1
            rightNum = left
    
            # 如果数组中没有target,则提前返回
            if right >= 0 and nums[right] != target:
                return 0
            
            # 2 搜索左边界
            left = 0
            right = len(nums) - 1
            while left <= right:
                mid = left + (right-left)//2
                if nums[mid] < target:
                    left = mid + 1
                else:
                    right = mid - 1
            leftNum = right
    
            return rightNum - leftNum - 1
    
    566-重塑数组

    输入:mat = [[1,2],[3,4]], r = 1, c = 4
    输出:[[1,2,3,4]]

    • 寻找映射关系
      # 映射关系:
      # 行:r = i//col 取整数
      # 列:c = i % col 取余数
    class Solution:
        def matrixReshape(self, mat: List[List[int]], r: int, c: int) -> List[List[int]]:
            row = len(mat)
            col = len(mat[0])
            if row*col != r*c:
                return mat
            res = [[0 for i in range(c)] for j in range(r)]
            for i in range(row*col):
                res[i//c][i%c] = mat[i//col][i%col]
            return res
    
    3-无重复字符的最长子串

    输入: "abcabcbb"
    输出: 3
    解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

    • 动态规划+哈希表
    class Solution:
        def lengthOfLongestSubstring(self, s: str) -> int:
            hashMap = {}
            left = 0
            maxLen = 0
            for index, val in enumerate(s):
                if val in hashMap:
                    left = max(left, hashMap[val]+1)
                hashMap[val] = index
                maxLen = max(maxLen, index-left+1)
            return maxLen
    
    21-合并两个有序的链表

    输入:l1 = [1,2,4], l2 = [1,3,4]
    输出:[1,1,2,3,4,4]

    • 方法1:使用递归
      递归表达式——总结出子问题
      情况1: list1[0] + merge(list[1:], list2[0]) if list1[0] < list2[0]
      情况2: list2[0] + merge(list[0], list2[1:]) if list1[0] >= list2[0]
      特别情况:当l1 或者 l2 是空链表
    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    
    class Solution:
        def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
            if l1 is None:
                return l2
            elif l2 is None:
                return l1
            elif l1.val < l2.val:      # 先连上较小的数
                l1.next = self.mergeTwoLists(l1.next, l2)
                return l1
            elif l1.val >= l2.val:
                l2.next = self.mergeTwoLists(l1, l2.next)
                return l2
    
    • 方法2:使用迭代
      思路:当l1和l2都不是空链表时,判断l1和l2哪一个链表的头结点的值更小,将较小值的节点添加到结果里面,当一个节点被添加到结果里面之后,将对应链表中的节点向后移动一位
    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
    
            # 定义一个新的链表
            prehead = ListNode(-1)
            prev = prehead
    
            while l1 and l2:             # 终止条件:都不为空
                if l1.val <= l2.val:
                    prev.next = l1
                    l1 = l1.next
                else:
                    prev.next = l2
                    l2 = l2.next
                prev = prev.next
            # 合并之后l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并的链表即可
            prev.next = l1 if l1 is not None else l2
            return prehead.next
    
    19-删除链表的倒数第n个结点

    输入:head = [1,2,3,4,5], n = 2
    输出:[1,2,3,5]

    • 方法1:使用双指针
    # Definition for singly-linked list.
    # class ListNode:
    #     def __init__(self, val=0, next=None):
    #         self.val = val
    #         self.next = next
    class Solution:
        def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
            # 双指针
            dummy = ListNode(0,head)     # 哑结点
            slow = dummy
            fast = head
            for i in range(n):           # slow和fast中间相隔两个 n 个结点
                fast = fast.next
            
            while fast is not None:      # 当fast到达末尾,slow所指的下一个节点将被删除
                slow = slow.next
                fast = fast.next
            
            # 删除节点元素
            slow.next = slow.next.next   
            
            return dummy.next
    

    相关文章

      网友评论

          本文标题:LeetCode刷题之《错题集》

          本文链接:https://www.haomeiwen.com/subject/vcjdwltx.html