Leetcode刷题记录本

Leetcode刷题记录本

ID: 1

  1. 暴力破解法
点击查看代码
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
		# 暴力破解法
        for i in range(len(nums)):
            for j in range(len(nums)):
                if nums[i]+nums[j]==target:
                    return [i,j]
  1. 使用字典,即key-map
点击查看代码
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        records = dict()
		# 字典以key-value的形式存储 实际的值和它对应的下标
        for index,value in enumerate(nums):
            if target-value in records:
                return [records[target-value],index]
            records[value] = index

ID: 704

  • 二分查找
点击查看代码
class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left, right = 0,len(nums)-1
        while left<=right:
            mid = (left+right)//2
            if nums[mid]<target:
                left = mid+1
            elif nums[mid]>target:
                right = mid-1
            else:
                return mid
        return -1

ID: 27

  • 快慢指针
点击查看代码
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        fast=slow=0
        n = len(nums)
        for fast, value in enumerate(nums):
            if nums[fast]!=val:
                nums[slow] = nums[fast]
                slow+=1
        return slow

ID: 977

  • 双向指针,相向而行
点击查看代码
class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        #定义左右指针
        left, right  = 0,len(nums)-1
        # 定义结果集
        res = [0]*len(nums)
        #定义结果集下标
        k=len(nums)-1
        # 最大值要么出现在最左端或者最右端,两个指针相向而行
        for index, value in enumerate(nums):
            if nums[left]*nums[left]<nums[right]*nums[right]:
                res[k] = nums[right]*nums[right]
                right-=1
            else:
                res[k] = nums[left]*nums[left]
                left+=1
            k-=1
        return res

ID: 209

  • 滑动窗口
点击查看代码
class Solution(object):
    def minSubArrayLen(self, target, nums):
        """
        :type target: int
        :type nums: List[int]
        :rtype: int
        """
        # 利用滑动窗口
        start = 0 #起始指针 
        sum_ = 0 # 用于求和
        min_len = 0
        for end, value in enumerate(nums):
            sum_+=nums[end] 
            while sum_ >= target: #满足条件后的窗口大小
                sub_len = end-start+1 
                if min_len==0:
                    min_len = sub_len
                else:
                    min_len = min(min_len,sub_len)
                sum_-=nums[start] #缩减窗口
                start+=1
        return min_len

ID: 203

  • 统一链表形式
点击查看代码
class Solution(object):
    def removeElements(self, head, val):
        """
        :type head: ListNode
        :type val: int
        :rtype: ListNode
        """
        # 设置虚拟头结点 再进行统一的移除节点操作
        dymmy_node = ListNode(next = head)
        # 用于遍历的临时指针cur(直接操作头结点,值会被修改,后面无法return头结点的值)
        cur = dymmy_node
        while cur.next!= None: #当前节点的下一个节点不为空
            if cur.next.val==val:
                cur.next = cur.next.next  # 将cur->next设置为cur->next->next并删除cur->next
            else:
                cur = cur.next
        return dymmy_node.next

ID: 207

  • 反转链表,双指针,pre,cur
点击查看代码
class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        # 双指针法
        cur = head #指向当前节点
        pre = None #指点前驱节点
        while cur!=None: 
            tmp = cur.next #把后继结点先存储起来
            cur.next = pre #把指针指向pre
            pre = cur #把当前节点反转为前驱节点
            cur = tmp #移动工作指针
        return pre

ID: 242

  • 定义一个26长度的数组,利用哈希表解题
点击查看代码
class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        # 定义一个数组,长度为26
        # 遍历s,把res对应位置的数值加1
        # 再遍历t,把res对应的位置数值减1
        # 最后结果如果都是0,则说明是;
        # ord是将字符转换为数值
        res = [0]*26
        for index,value in enumerate(s):
            res[ord(value)-ord('a')]+=1
        for index,value in enumerate(t):
            res[ord(value)-ord('a')]-=1
        for index,value in enumerate(res):
            if value != 0:
                return False
        return True

ID: 349

  • 直接利用python的set特性
点击查看代码
class Solution(object):
    def intersection(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        res = list(set(nums1)&set(nums2))
        return res

ID: 349

  • 利用python的set存储每次的数字,如果陷入循环了,直接返回false
点击查看代码
class Solution(object):
    def isHappy(self, n):
        """
        :type n: int
        :rtype: bool
        """
        res = set()
        while n!= 1:
            sum_ = 0
            if n in res:
                return False
            res.add(n)
            # 取n的每一位数字
            for num in str(n):
                sum_+=int(num)**2
            n = sum_
        return True

ID: 383

  • 这道题和242题很像,都用一个26长度的数组存储字符
点击查看代码
class Solution(object):
    def canConstruct(self, ransomNote, magazine):
        """
        :type ransomNote: str
        :type magazine: str
        :rtype: bool
        """
        # 这题和242的字母异位词的题类似
        res = [0]*26
        for index,value in enumerate(magazine):
            res[ord(value)-ord('a')]+=1
        for index,value in enumerate(ransomNote):
            #如果ransomNote出现的字符在magazine没有,则直接返回false
            if res[ord(value)-ord('a')]==0:
                return False  
            # 这一步的-1不要忘了,因为value只能使用一次,不能重复使用
            else:
                res[ord(value)-ord('a')]-=1
        return True

ID: 344

  • 左右双指针
点击查看代码
class Solution(object):
    def reverseString(self, s):
        """
        :type s: List[str]
        :rtype: None Do not return anything, modify s in-place instead.
        """
        #左右指针法
        left, right = 0, len(s)-1
        # 这里的判定条件得写好! 不能用mid,也不要用!=
        while(left<=right):
            s[left] , s[right] = s[right], s[left]
            left+=1
            right-=1
        return s

ID: 144

  1. 二叉树的前序遍历,使用递归,函数里定义出口、在函数里递归;
点击查看代码
class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        def pre_order(root):
            if root==None:
                return
            res.append(root.val)
            pre_order(root.left)
            pre_order(root.right)
		#来个入口函数,调用一次
        pre_order(root)
        return res
  1. 使用迭代法(循环法),需要借助到栈
点击查看代码
class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        if root==None:
            return res
        stack = [root]
        while stack:
            node = stack.pop()
            res.append(node.val)
            #利用栈先进后出的特点,确保先把右子树压入栈,这样子左子树一定先出来
            if node.right:
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return res

ID: 145

  1. 二叉树的后序遍历,使用递归,函数里定义出口、在函数里递归;最后入口调用不要忘了
点击查看代码
class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        #跟前序一样,自己实现一遍
        res = []
        #使用递归法
        def post_order(root):
            if root==None:
                return 
            post_order(root.left)
            post_order(root.right)
            res.append(root.val)
        post_order(root)
        return res
  1. 使用迭代法(循环法),需要借助到栈;前序:根-左-后,先调换 根-右-左,再逆序输出,左-右-根
点击查看代码
class Solution(object):
    def postorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        #跟前序一样,自己实现一遍
        res = []
        #使用栈来实现
        # 跟前序差不多,只不过需要调换顺序:
        # 前序:根-左-后,先调换 根-右-左,再逆序输出,左-右-根
        stack = [root]
        while stack:
            node = stack.pop()
            res.append(node.val)
            #先把左子树压入栈,确保顺序是 右-左
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
        ## list[::-1]表示列表逆序输出,python的特性,可以用
        return res[::-1]

ID: 99

  1. 二叉树的中序遍历,使用递归,函数里定义出口、在函数里递归;最后入口调用不要忘了
点击查看代码
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        def in_order(root):
            if root==None:
                return
            in_order(root.left)
            res.append(root.val)
            in_order(root.right)
        in_order(root)
        return res  
  1. 使用迭代法(循环法),需要借助到栈;不能像上面一样做了,需要一个工作指针,这道题值得做第二遍
点击查看代码
class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        stack = []
        cur = root #不能像上面一样做了,需要一个工作指针
        while cur or stack:
            if cur:
                stack.append(cur) #这一行不仅只针对左子树,工作指针用于指向当前的树
                cur = cur.left
            else:
                node = stack.pop()
                res.append(node.val)
                if node.right:
                    cur = node.right
        return res   

ID: 102

  1. 二叉树的层序遍历,使用递归
点击查看代码
class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        res = []
        def level_order(root,depth):
            # 出口条件
            if root==None:
                return 
            # 添加层数
            if len(res)==depth:
                res.append([])
            #深搜,对于每一个深度,即每一层设置值
            res[depth].append(root.val)
            level_order(root.left,depth+1)
            level_order(root.right,depth+1)
        level_order(root,0)
        return res

ID: 107

  1. 二叉树的逆序层序遍历,使用递归;相较上一题,直接先正着层序遍历,再把结果数组翻一下。
点击查看代码
class Solution(object):
    def levelOrderBottom(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        res = []
        def level_order(root,depth):
            if root==None:
                return
            if len(res)==depth:
                res.append([])
            res[depth].append(root.val)
            level_order(root.left,depth+1)
            level_order(root.right,depth+1)
        level_order(root,0)
        return res[::-1]

ID: 199

  1. 二叉树的右视图,使用队列来实现,判断最每一层最右边的结点。
点击查看代码
class Solution(object):
    def rightSideView(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        # 每一层的最右边的那个结点即是答案,判断每一层是否是最右边的结点
        res = []
        #使用队列来实现
        from collections import deque       
        if root==None:
            return []

        que = deque([root])
        while que:
            # 每次都取最后一个结点,这里不用pop的原因是pop会删除最后一个元素
            node = que[-1]
            res.append(node.val)

            # 遍历获取每一层的所有node
            for _ in range(len(que)):
                node = que.popleft()
                if node.left:
                    que.append(node.left)
                if node.right:
                    que.append(node.right)
        return res

ID: 637

  1. 二叉树的每一层的平均数。
点击查看代码
class Solution(object):
    def averageOfLevels(self, root):
        """
        :type root: TreeNode
        :rtype: List[float]
        """
        res = []
        final_res = []
        def level_order(root,depth):
            if root==None:
                return 
            if len(res) == depth:
                res.append([])
            res[depth].append(root.val)
            if root.left:
                level_order(root.left,depth+1)
            if root.right:
                level_order(root.right,depth+1)
        level_order(root,0)
        for index,value in enumerate(res):
            avg = sum(value)*1.0/len(value)
            final_res.append(avg)
        return final_res

ID: 429

  1. N叉树的层序遍历。
点击查看代码
class Solution(object):
    def levelOrder(self, root):
        """
        :type root: Node
        :rtype: List[List[int]]
        """
        final_res = []
        from collections import deque
        que = deque([root])
        while que:
            res = []
            # 这里还有一个循环
            for _ in range(len(que)):
                cur = que.popleft()
                res.append(cur.val)
                if cur.children:
                    #注意这里是extend()
                    que.extend(cur.children)
            final_res.append(res)
        return final_res

ID: 515

  1. 在每个树行中找最大值,没什么好说的,跟前面的一样。
点击查看代码
class Solution(object):
    def largestValues(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        final_res = []
        def level_order(root,depth):
            if root==None:
                return 
            if len(res) == depth:
                res.append([])
            res[depth].append(root.val)
            if root.left:
                level_order(root.left,depth+1)
            if root.right:
                level_order(root.right,depth+1)
        level_order(root,0)
        for index,value in enumerate(res):
            max_ = max(value)
            final_res.append(max_)
        return final_res

ID: 513

  1. 找树的最下层的最左边的元素,注意这里的坑是它没说是完全二叉树,所以那个元素不一定就出现在最最左边,所以不能用深度递归。
点击查看代码
class Solution(object):
    def findBottomLeftValue(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        target = 0
        from collections import deque
        que = deque([root])
        while que:
            for i in range(len(que)):
                cur = que.popleft()
                # 判断每一层的第一个元素
                if i ==0:
                    target=cur.val
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
        return target

ID: 116

  1. 填充每个节点的下一个右侧节点指针。
    解题思路:在层序遍历时,记录本层的头部节点,然后在遍历的时候让前一个节点指向本节点就可以了。
点击查看代码
class Solution(object):
    def connect(self, root):
        """
        :type root: Node
        :rtype: Node
        """
        from collections import deque
        que = deque([root])
        while que:
            size = len(que)
            #单层遍历
            for i in range(size):
                cur = que.popleft()
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
                # 这里需要终止掉,因为最后要确保每一层的que里至少有两个元素
                if i==size-1:
                    break
                cur.next = que[0]
        return root

ID: 117

  1. 填充每个节点的下一个右侧节点指针。
    解题思路:设置一个指针用于记录上一个结点,这题的答案可以适用于ID: 116
点击查看代码
class Solution(object):
    def connect(self, root):
        """
        :type root: Node
        :rtype: Node
        """
        #开头不要忘了判断空值
        if root==None:
            return 
        from collections import deque
        que = deque([root])
        while que:
            size = len(que)
            #设置一个指针用于记录上一个结点
            tail = None
            #单层遍历
            for i in range(size):
                cur = que.popleft()
                # 此后都让上一个指针指向当前指针
                if tail:
                    tail.next = cur
                #初始的时候将工作指针赋给tail
                tail = cur
                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)
        return root

ID: 104

  1. 二叉树的最大深度,层序遍历的题,没啥好说的。
点击查看代码
class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        res = []
        def level_order(root,depth):
            if root==None:
                return 
            if len(res) == depth:
                res.append([])
            res[depth].append(root.val)
            if root.left:
                level_order(root.left,depth+1)
            if root.right:
                level_order(root.right,depth+1)
        level_order(root,0)
        return len(res)

ID: 111

  1. 二叉树的最小深度
点击查看代码
class Solution(object):
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if root==None:
            return 0
        from collections import deque
        # que里面存储的是一个tuple,再外面套一个列表,标准格式
        que = deque([(root,1)])
        while que:
            size = len(que)
            for i in range(size):
                #取的时候也是这么取
                node,depth = que.popleft()
                if node.left==None and node.right==None:
                    return depth
                if node.left:
                    que.append((node.left,depth+1))
                if node.right:
                    que.append((node.right,depth+1))
        return 0

ID: 226

  1. 翻转二叉树
点击查看代码
class Solution(object):
    def invertTree(self, root):
        """
        :type root: TreeNode
        :rtype: TreeNode
        """
        # 层序遍历,,把每个节点的左右孩子都翻转一遍
        if root==None:
            return
        from collections import deque
        que = deque([root])
        while que:
            node = que.popleft()
            if node.left:
                que.append(node.left)
            if node.right:
                que.append(node.right)
            # 不只是调换值,还需要调换整个分支,因此不能简单地用.val
            if node.left and node.right:
                node.left, node.right = node.right, node.left
        return root
posted @ 2023-08-09 16:33  梁君牧  阅读(14)  评论(0编辑  收藏  举报