LT

206. 反转链表

    def reverseList(self, head: ListNode) -> ListNode:
        prev = NoListNodene
        cur = head
        while(cur):
            tmp = cur.next
            cur.next = prev
            prev = cur
            cur = tmp
        return prev

124. 二叉树中的最大路径和

    def maxPathSum(self, root: TreeNode) -> int:
        self.res = float("-inf")
        def dfs(root):
            if not root:
                return 0
            left = dfs(root.left)
            right = dfs(root.right)
            left = max(left, 0)
            right = max(right, 0)
            self.res = max(self.res,  root.val + left + right)
            return root.val + max(left, right)
        
        dfs(root)
        return self.res

23. 合并K个升序链表

      def mergeKLists(self, lists):
        import heapq
        head = point = ListNode(0)
        heap = []
        for l in lists:
            while l:
                heapq.heappush(heap, l.val)
                l = l.next
        while heap:
            val = heappop(heap)
            point.next = ListNode(val)
            point = point.next
        return head.next

25. K 个一组翻转链表

          # 翻转一个子链表,并且返回新的头与尾。反转前的head是反转后的new_tail,反转后的头是prev指针
    def reverse(self, head: ListNode, tail: ListNode):
        prev = None
        cur = head
        new_tail = head

        while prev != tail:
            tmp = cur.next
            cur.next = prev
            prev = cur
            cur = tmp

        return prev, new_tail

    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:
        dummy = ListNode(0)
        dummy.next = head
        pre = dummy

        while head:
            tail = pre
            # 查看剩余部分长度是否大于等于 k
            for i in range(k):
                tail = tail.next
                if not tail:
                    return dummy.next
            nex = tail.next
            head, tail = self.reverse(head, tail)
            # 把子链表重新接回原链表
            pre.next = head
            tail.next = nex
            pre = tail
            head = tail.next
        
        return dummy.next

92. 反转链表 II

      def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
        def reverse_linked_list(head: ListNode):
            # 也可以使用递归反转一个链表
            pre = None
            cur = head
            while cur:
                next = cur.next
                cur.next = pre
                pre = cur
                cur = next

        # 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
        dummy_node = ListNode(-1)
        dummy_node.next = head
        pre = dummy_node
        # 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
        # 建议写在 for 循环里,语义清晰
        for _ in range(left - 1):
            pre = pre.next

        # 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
        right_node = pre
        for _ in range(right - left + 1):
            right_node = right_node.next
        # 第 3 步:切断出一个子链表(截取链表)
        left_node = pre.next
        curr = right_node.next

        # 注意:切断链接
        pre.next = None
        right_node.next = None

        # 第 4 步:同第 206 题,反转链表的子区间
        reverse_linked_list(left_node)
        # 第 5 步:接回到原来的链表中
        pre.next = right_node
        left_node.next = curr
        return dummy_node.next

786. 第 K 个最小的素数分数

   def kthSmallestPrimeFraction(self, arr: List[int], k: int) -> List[int]:
        def cmp(x: Tuple[int, int], y: Tuple[int, int]) -> int:
            return -1 if x[0] * y[1] < x[1] * y[0] else 1
        
        n = len(arr)
        frac = list()
        for i in range(n):
            for j in range(i + 1, n):
                frac.append((arr[i], arr[j]))
        
        frac.sort(key=cmp_to_key(cmp))
        return list(frac[k - 1])

42. 接雨水

    def trap(self, height: List[int]) -> int:
        if not height:
            return 0
        left_max = [height[0]]
        for i in range(1, len(height)):
            left_max.append(max(left_max[i-1],height[i]))

        right_max = [0]*(len(height)-1) + [height[-1]]
        for i in range(len(height)-2, -1, -1):
            right_max[i] =  max(right_max[i+1],height[i])

        res = 0
        for i in range(len(height)):
            res = res +  min(left_max[i],right_max[i] )-height[i]

        return res

209. 长度最小的子数组

       def minSubArrayLen(self, target: int, nums: List[int]) -> int:
        left=0
        mincount=float('inf')
        cursum=0
        
        for right in range(len(nums)):
            cursum+=nums[right]
            
            while cursum>=target:
                mincount=min(mincount,right-left+1)
                cursum=cursum-nums[left]
                left+=1
        
        return mincount if mincount!=float('inf') else 0
 

509. 斐波那契数

     def fib(self, n: int) -> int:
        res = [0]*(n+1)
        if n==0:
            return 0
        if n==1:
            return 1
        res[0] = 0
        res[1] = 1 
        for i in range(2, n+1):
            res[i] = res[i-1] + res[i-2]
 
        return res[-1]
 

470. 用 Rand7() 实现 Rand10()

(rand_X() - 1) × Y + rand_Y() ==> 可以等概率的生成[1, X * Y]范围的随机数

    def rand10(self):
        num =  (rand7()-1)*7 + rand7()
        while num>40:
            num =  (rand7()-1)*7 + rand7()  #拒绝采样,重新生成
        return num%10 +1

        # https://leetcode.cn/problems/implement-rand10-using-rand7/solution/cong-zui-ji-chu-de-jiang-qi-ru-he-zuo-dao-jun-yun-/
 

329. 矩阵中的最长递增路径

    def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
           DIRS = [(-1, 0), (1, 0), (0, -1), (0, 1)]

    def longestIncreasingPath(self, matrix: List[List[int]]) -> int:
        if not matrix:
            return 0
        
        @lru_cache(None)
        def dfs(row: int, column: int) -> int:
            best = 1
            for dx, dy in Solution.DIRS:
                newRow, newColumn = row + dx, column + dy
                if 0 <= newRow < rows and 0 <= newColumn < columns and matrix[newRow][newColumn] > matrix[row][column]:
                    best = max(best, dfs(newRow, newColumn) + 1)
            return best

        ans = 0
        rows, columns = len(matrix), len(matrix[0])
        for i in range(rows):
            for j in range(columns):
                ans = max(ans, dfs(i, j))
        return ans

560. 和为 K 的子数组

   def subarraySum(self, nums: List[int], k: int) -> int:
        hashtable = {0:1}
        ret = 0
        pre_sum = 0
        for num in nums:
            pre_sum += num
            ret += hashtable.get(pre_sum - k, 0) 
            hashtable[pre_sum] = hashtable.get(pre_sum, 0) + 1
        return ret


        # 所以判断当前元素与k之间的差值是否是前若干元素总和即可,注意计数时并不都是+1,如果前若干元素总和=nums[j]-k的子数组个数大于1,则要全部加上,因为是不同的子数组。(因为中间可能有一段和为0,座椅可能有多个)

51. N 皇后

剑指 Offer 51. 数组中的逆序对

    def reversePairs(self, nums: List[int]) -> int:
 
        count = 0
        alist = []
        for n in nums:
            idx = bisect.bisect(alist, n)
            alist.insert(idx, n)
            count = count + len(alist)-idx-1

        return count

611. 有效三角形的个数

    def triangleNumber(self, nums: List[int]) -> int:
        res = 0
        nums.sort()
        
        for i in range(2, len(nums)):
            l, r = 0, i - 1
            while l < r:
                if nums[l] + nums[r] <= nums[i]:
                    l += 1
                else:
                    res += r - l
                    r -= 1
        
        return res

85. 最大矩形

    def maximalRectangle(self, matrix: List[List[str]]) -> int:

        # time O(mn), space O(n)
        if not matrix or not matrix[0]:
            return 0
        
        self.res = 0
        
        def helper(arr):            
            stack = []
            
            for i in range(len(arr)):
                while stack and arr[i] < arr[stack[-1]]:
                    idx = stack.pop()
                    width = i - stack[-1] - 1
                    height = arr[idx]
                    self.res = max(self.res, width * height)
                
                stack.append(i)
                    
 
        r, c = len(matrix), len(matrix[0])
        
        cnts = [0] * (c + 2)
        
        for i in range(r):
            for j in range(c):
                if matrix[i][j] == '1':
                    cnts[j + 1] += 1
                else:
                    cnts[j + 1] = 0
            helper(cnts)
         
        return self.res

912. 排序数组

def sortArray(self, nums: List[int]) -> List[int]:

        def QuickSort(left, right):
            if left >= right: return nums
            index = random.randint(left, right)
            pivot = nums[index]
            nums[index], nums[left] = nums[left], nums[index]
            i, j = left, right
            while i < j:
                while i < j and nums[j] > pivot:
                    j -= 1
                nums[i] = nums[j]
                while i < j and nums[i] <= pivot:
                    i += 1
                nums[j] = nums[i]
            nums[i] = pivot
            QuickSort(left, i-1)
            QuickSort(i+1, right)
            return nums

        QuickSort(0, len(nums)-1)
        return nums

572. 另一棵树的子树

    def isSubtree(self, s, t):
        """
        :type s: TreeNode
        :type t: TreeNode
        :rtype: bool
        """
        if not s and not t:
            return True
        if not s or not t:
            return False
        return self.isSameTree(s, t) or self.isSubtree(s.left, t) or self.isSubtree(s.right, t)
        
    def isSameTree(self, s, t):
        if not s and not t:
            return True
        if not s or not t:
            return False
        return s.val == t.val and self.isSameTree(s.left, t.left) and self.isSameTree(s.right, t.right)

55. 跳跃游戏

    def canJump(self, nums: List[int]) -> bool:
        n, reach = len(nums), 0
        for i in range(n):
            if i > reach:
                return False
            reach = max(reach, i + nums[i])

        return True

45. 跳跃游戏 II

    def jump(self, nums: List[int]) -> int:
 
        n = len(nums)
        maxPos, end, step = 0, 0, 0
        for i in range(n - 1):
            if maxPos < i:
                return
            maxPos = max(maxPos, i + nums[i])
            if i == end:  #我们从左到右遍历数组,到达边界时,更新边界并将跳跃次数增加 1。
                end = maxPos
                step += 1
        return step

887. 鸡蛋掉落

    ans = N
    # 暴力枚举从第 i 层开始扔,碎了往下试探并少一个鸡蛋,没碎往上试探
    for i in range(1, N + 1):
        ans = min(ans, max(self.superEggDrop(K - 1, i - 1) + 1, self.superEggDrop(K,  N - i) + 1))
    return ans

 
#dp[x][y] 表示 x次操作y个鸡蛋  可以确认多少层,即不管你这个鸡蛋在dp[x][y]及其下面那一层会碎,我们都能查出f。看看dp[m] 怎么由dp[m-1]转换过来。假设dp[m - 1][i - 1] 确定了一个楼层A。那么dp[m - 1][i]表示鸡蛋没碎可以往上再试探的楼层数量 
     def superEggDrop(self, K: int, N: int) -> int:
        dp = [[0] * (K + 1) for _ in range(N + 1)]
        m = 0
        while dp[m][K] < N:
            m += 1
            for i in range(1, K + 1):
                dp[m][i] = dp[m - 1][i - 1] + dp[m - 1][i]  + 1
        return m

206. 反转链表

    def reverseList(self, head: ListNode) -> ListNode:
        prev = None
        cur = head 

        while cur:
            tmp = cur.next
            cur.next = prev
            prev = cur
            cur = tmp
        
        return prev

92. 反转链表 II

   def reverseBetween(self, head: ListNode, left: int, right: int) -> ListNode:
        def reverse_linked_list(head: ListNode):
            # 也可以使用递归反转一个链表
            pre = None
            cur = head
            while cur:
                next = cur.next
                cur.next = pre
                pre = cur
                cur = next

        # 因为头节点有可能发生变化,使用虚拟头节点可以避免复杂的分类讨论
        dummy_node = ListNode(-1)
        dummy_node.next = head
        pre = dummy_node
        # 第 1 步:从虚拟头节点走 left - 1 步,来到 left 节点的前一个节点
        # 建议写在 for 循环里,语义清晰
        for _ in range(left - 1):
            pre = pre.next

        # 第 2 步:从 pre 再走 right - left + 1 步,来到 right 节点
        right_node = pre
        for _ in range(right - left + 1):
            right_node = right_node.next
        # 第 3 步:切断出一个子链表(截取链表)
        left_node = pre.next
        curr = right_node.next

        # 注意:切断链接
        pre.next = None
        right_node.next = None

        # 第 4 步:同第 206 题,反转链表的子区间
        reverse_linked_list(left_node)
        # 第 5 步:接回到原来的链表中
        pre.next = right_node
        left_node.next = curr
        return dummy_node.next

101. 对称二叉树

     def isSymmetric(self, root: TreeNode) -> bool:
        # write code here
        if not root:
            return True
        def Traversal(left, right):
            if left is None and right is None:#如果是叶节点,直接返回True
                return True
            #如果左右节点相同,继续判断左-左和右-右,以及左-右和右-左
            elif left and right and left.val == right.val:
                return Traversal(left.left, right.right) and Traversal(left.right, right.left)
            else:
                return False
        return Traversal(root.left, root.right)

226. 翻转二叉树

  def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return None
        tmp_left = root.left
        root.left = self.invertTree(root.right)
        root.right = self.invertTree(tmp_left)
        return root

295. 数据流的中位数

class MedianFinder:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.big_heap = []
        self.small_heap = []

    def addNum(self, num: int) -> None:
        if len(self.big_heap) == len(self.small_heap):
            heapq.heappush(self.small_heap, -num)
            heapq.heappush(self.big_heap, - heapq.heappop(self.small_heap))
        else:
            heapq.heappush(self.big_heap,  num)
            heapq.heappush(self.small_heap, - heapq.heappop(self.big_heap))

    def findMedian(self) -> float:
        if len(self.big_heap) == len(self.small_heap):
            return ( self.big_heap[0] - self.small_heap[0]) / 2
        else:
            return  self.big_heap[0]

110. 平衡二叉树

def isBalanced(self, root: TreeNode) -> bool:

        def dfs(root):
            if not root:
                return 0
            left = dfs(root.left)
            right = dfs(root.right)
            return max(left,right) +1

        if not root:
            return True
            
        l = dfs(root.left)
        r = dfs(root.right)
        if abs(l-r)<=1:
            return self.isBalanced(root.left) and self.isBalanced(root.right)
        else:
            return False

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容