Leetcode刷题

刷题

leetcode

1.两数之和

#哈希表
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        hashtable = dict()
        for i, item in enumerate(nums):
            if target-item in hashtable:
                return [hashtable[target-item],i]
            hashtable[item] = i
        return []

#yy暴力
class Solution:

    def twoSum(self, nums: List[int], target: int) -> List[int]:
        for i in nums:
            tmp = nums[nums.index(i)+1:]
            if target-i in tmp:
                return [nums.index(i), nums.index(i)+tmp.index(target-i)+1]

8.回文数

#数学解法
class Solution:
    def isPalindrome(self, x: int) -> bool:
        if x>=0 and x<10 :
            return True
        if x!=0 and x%10 == 0: #前面已经判断了,可以不判断0
            return False
        if x<0:
            return False
        rx=0
        while(rx<x):
            rx = 10*rx + x%10
            x = x//10
            print("rx, x", rx,x)
            if rx ==x:
                return True
        if rx>x and rx//10==x:
            return True
        else:
            return False
#字符串反转
class Solution(object):
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        xm = str(x)
        xR = ''.join(reversed(xm))
        return xm==xR

2022/1/19

704.二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        length = len(nums)
        high = length-1
        low = 0
        while low<=high :
            mid = (low+high)/2
            if nums[mid]==target:
                return mid
            elif nums[mid]>target:
                high = mid-1
            elif nums[mid]<target:
                low = mid+1
        return -1

278.第一个错误的版本

class Solution:
    def firstBadVersion(self, n):
        """
        :type n: int
        :rtype: int
        """
        l, r = 1, n
        while l <= r: # 重点一:l <= r
            mid = (l+r)//2
            if isBadVersion(mid):
                r = mid - 1
            else:
                l = mid + 1
        return l # 重点二:return l

2022/1/20

977.有序数组的平方

class Solution:
    def sortedSquares(self, nums: List[int]) -> List[int]:
        neg,length = -1, len(nums)
        for i, num in enumerate(nums):
            if num<0:
                neg = i
        ans = list()
        p,q = neg,neg+1
        while p>=0 or q<length:
            if p<0:
                ans.append(nums[q]*nums[ q])
                q+=1
            elif q==length:
                ans.append(nums[p]*nums[p])
                p-=1
            elif nums[p]*nums[p] <= nums[q]*nums[q]:
                ans.append(nums[p]*nums[p])
                p-=1
            elif nums[p]*nums[p] > nums[q]*nums[q]:
                ans.append(nums[q]*nums[q])
                q+=1
        return ans

189.轮转数组

#复制数组
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        tmp = nums[0]
        length = len(nums)
        ans = list(nums)
        for i in range(length):
            nums[(i+k)%length] = ans[i]
class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """		
		n = len(nums)
        k %= n
        nums.reverse()
        nums[:k] = list(reversed(nums[:k]))
        nums[k:] = list(reversed(nums[k:]))

2022/1/21

283.移动零

#计数覆盖
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        h, nonzero, move = 0, 0, 0
        length = len(nums)
        while nonzero<length:
            if nums[nonzero]!=0:
                nums[h]=nums[nonzero] 
                h+=1
            nonzero+=1
        for i in range(h, length):
            nums[i]=0
#双指针
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        n = len(nums)
        left = right = 0
        while right < n:
            if nums[right] != 0:
                nums[left], nums[right] = nums[right], nums[left]
                left += 1
            right += 1
            print(nums)

167. 两数之和 II - 输入有序数组

class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        length = len(numbers)
        left,right = 0, length-1
        while left < right:
            total = numbers[left]+numbers[right]
            if total == target:
                return [left+1, right+1]
            elif total < target:
                left+=1
            elif total > target:
                right-=1
        return [-1,-1]

2022\1\22

#列表切片
class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        s[:]=s[::-1]


#s[::-1]表示反转s中的元素
#s[:]表示数组中所有子模块
#s[:]=s[::-1]表示将原数组反转后赋值给s中每一个对应的位置
#s=s[::-1]表示将s反转后赋值给新的对象s(可以通过id函数查看内存地址),与题意原地修改不符。
代码

作者:yim-6
链接:https://leetcode-cn.com/problems/reverse-string/solution/python3-liang-chong-fang-fa-shi-xian-fan-zhuan-zi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#双指针
class Solution:
    def reverseString(self, s: List[str]) -> None:
        """
        Do not return anything, modify s in-place instead.
        """
        length = len(s)
        left, right =0, length-1
        while left < right:
            tmp = s[left]
            s[left] = s[right]
            s[right] = tmp
            left+=1
            right-=1

557. 反转字符串中的单词 III

#双指针
class Solution:
    def reverseWords(self, s: str) -> str:
        ans = ''
        words = s.split(' ')
        for idx, word in enumerate(words):
            rs = ''.join(reversed(word))
            ans = ans + rs
            print(idx)
            if idx!=len(words)-1:
                ans = ans + ' '
        return ans

class Solution(object):
    def reverseWords(self, s):
        return " ".join(word[::-1] for word in s.split(" "))


作者:swants
链接:https://leetcode-cn.com/problems/reverse-words-in-a-string-iii/solution/python-fan-zhuan-zi-fu-chuan-zhong-dan-ci-si-lu-xi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2022/1/24

876. 链表的中间结点

# 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:
        slow, fast = head, head
        while fast != None:
            if fast.next == None:
                return slow
            if fast.next == None:
                return slow.next
            slow = slow.next
            fast = fast.next.next
        return slow
class Solution:
    def middleNode(self, head: ListNode) -> ListNode:
        slow = fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
        return slow


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/middle-of-the-linked-list/solution/lian-biao-de-zhong-jian-jie-dian-by-leetcode-solut/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

567. 字符串的排列

class Solution:
    def checkInclusion(self, s1: str, s2: str) -> bool:
        counter1 = collections.Counter(s1)
        n1, n2 = len(s1), len(s2)
        left = 0
        right = left + n1
        while right<=n2 and left <=n2:
            counter2 = collections.Counter(s2[left:right])
            if counter1 == counter2:
                return True
            left+=1
            right+=1
        return False
class Solution(object):
    def checkInclusion(self, s1, s2):
        """
        :type s1: str
        :type s2: str
        :rtype: bool
        """
        # 统计 s1 中每个字符出现的次数
        counter1 = collections.Counter(s1)
        N = len(s2)
        # 定义滑动窗口的范围是 [left, right],闭区间,长度与s1相等
        left = 0
        right = len(s1) - 1
        # 统计窗口s2[left, right - 1]内的元素出现的次数
        counter2 = collections.Counter(s2[0:right])
        while right < N:
            # 把 right 位置的元素放到 counter2 中
            counter2[s2[right]] += 1
            # 如果滑动窗口内各个元素出现的次数跟 s1 的元素出现次数完全一致,返回 True
            if counter1 == counter2:
                return True
            # 窗口向右移动前,把当前 left 位置的元素出现次数 - 1
            counter2[s2[left]] -= 1
            # 如果当前 left 位置的元素出现次数为 0, 需要从字典中删除,否则这个出现次数为 0 的元素会影响两 counter 之间的比较
            if counter2[s2[left]] == 0:
                del counter2[s2[left]]
            # 窗口向右移动
            left += 1
            right += 1
        return False


# 作者:fuxuemingzhu
# 链接:https://leetcode-cn.com/problems/permutation-in-string/solution/zhu-shi-chao-xiang-xi-de-hua-dong-chuang-rc7d/
# 来源:力扣(LeetCode)
# 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2022/1/25 (广度优先搜索/宽度优先搜索)

733. 图像渲染

#广度优先
class Solution:
    def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]:
        currColor = image[sr][sc]
        if currColor == newColor:
            return image
        
        n, m = len(image), len(image[0])
        que = collections.deque([(sr, sc)])
        image[sr][sc] = newColor
        while que:
            x, y = que.popleft()
            for mx, my in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:
                if 0 <= mx < n and 0 <= my < m and image[mx][my] == currColor:
                    que.append((mx, my))
                    image[mx][my] = newColor
        
        return image
#深度优先搜索
class Solution:
    def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]:
        n, m = len(image), len(image[0])
        currColor = image[sr][sc]

        def dfs(x: int, y: int):
            if image[x][y] == currColor:
                image[x][y] = newColor
                for mx, my in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:
                    if 0 <= mx < n and 0 <= my < m and image[mx][my] == currColor:
                        dfs(mx, my)

        if currColor != newColor:
            dfs(sr, sc)
        return image


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/flood-fill/solution/tu-xiang-xuan-ran-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

695. 岛屿的最大面积

#深度优先搜索 
class Solution:
    def dfs(self, grid, cur_i,cur_j):
        if cur_i < 0 or cur_j <0 or cur_i == len(grid) or cur_j == len(grid[0]) or grid[cur_i][cur_j]==0 :
            return 0
        grid[cur_i][cur_j]=0
        ans = 1
        for di, dj in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
            next_i, next_j = cur_i + di, cur_j + dj
            ans += self.dfs(grid, next_i, next_j) 
        return ans

    def maxAreaOfIsland(self, grid: List[List[int]]) -> int:
        ans = 0
        for i, l in enumerate(grid):
            for j, n in enumerate(l):
                ans = max(self.dfs(grid, i, j), ans)
        return ans

2022/1/26

617. 合并二叉树

# 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 mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
        if not root1:
            return root2
        if not root2:
            return root1
         
        merged = TreeNode(root1.val+root2.val)
        merged.left = self.mergeTrees(root1.left, root2.left)
        merged.right = self.mergeTrees(root1.right, root2.right)
        return merged

116. 填充每个节点的下一个右侧节点指针

层次遍历基于广度优先搜索,它与广度优先搜索的不同之处在于,广度优先搜索每次只会取出一个节点来拓展,而层次遍历每次将队列中的所有元素都拿出来拓展,这样能保证每次从队列中拿出来遍历的元素都是属于同一层的,因此我们可以在遍历的过程中修改每个节点的 next 指针,同时拓展下一层的新队列。

import collections 

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        
        if not root:
            return root
        
        # 初始化队列同时将第一层节点加入队列中,即根节点
        Q = collections.deque([root])
        
        # 外层的 while 循环迭代的是层数
        while Q:
            
            # 记录当前队列大小
            size = len(Q)
            
            # 遍历这一层的所有节点
            for i in range(size):
                
                # 从队首取出元素
                node = Q.popleft()
                
                # 连接
                if i < size - 1:
                    node.next = Q[0]
                
                # 拓展下一层节点
                if node.left:
                    Q.append(node.left)
                if node.right:
                    Q.append(node.right)
        
        # 返回根节点
        return root


#作者:LeetCode-Solution
#链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/solution/tian-chong-mei-ge-jie-dian-de-xia-yi-ge-you-ce-2-4/
#来源:力扣(LeetCode)
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2022/1/27

广度优先搜索和宽度优先搜索

542. 01 矩阵

class Solution:
    def updateMatrix(self, mat: List[List[int]]) -> List[List[int]]:
        m, n = len(mat), len(mat[0])
        dist = [[0] * n for _ in range(m)]
        zeroes_pos = [(i, j) for i in range(m) for j in range(n) if mat[i][j]==0]
        q = collections.deque(zeroes_pos)
        seen = set(zeroes_pos)

        while q:
            i, j = q.popleft()
            for ni, nj in [(i+1, j), (i-1, j), (i, j+1), (i, j-1)]:
                if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in seen:
                    dist[ni][nj] = dist[i][j]+1
                    q.append((ni, nj))
                    seen.add((ni, nj))
        return dist

994. 腐烂的橘子

class Solution:
    def orangesRotting(self, grid: List[List[int]]) -> int:
        R, C = len(grid), len(grid[0])
        queue = collections.deque()
        for r, row in enumerate(grid):
            for c, val in enumerate(row):
                if val == 2:
                    queue.append((r,c,0))
                    
        def neighbors(r, c)->(int, int):
            for nr, nc in [(r+1, c), (r-1, c), (r, c-1), (r,c+1)]:
                if 0<=nr

2022/1/28

递归\回溯

21. 合并两个有序链表

#迭代写法
# 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: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        prehead = ListNode(-1)
        prev = prehead
        
        while l1 and l2:
            if l1.val <= l2.val:
                prev.next = l1
                l1 = l1.next
                prev = prev.next
            else:
                prev.next = l2
                l2 = l2.next
                prev = prev.next
        prev.next = l1 if l1 is not None else l2
        return prehead.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
        else:
            l2.next = self.mergeTwoLists(l1, l2.next)
            return l2


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

206. 反转链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        st = collections.deque()
        while head:
            st.append(head.val)
            head = head.next
        prehead = ListNode(-1)
        prev = prehead
        for i in range(len(st)):
            tmp = ListNode(st.pop()) 
            prev.next = tmp
            prev = prev.next
        return prehead.next

剑指offer

2022/2/23

栈与队列(简单)

Leetcode刷题_第1张图片

剑指 Offer 09. 用两个栈实现队列

class CQueue:

    def __init__(self):
        self.A, self.B = [],[]

    def appendTail(self, value: int) -> None:
        self.A.append(value)



    def deleteHead(self) -> int:
        if self.B:
            return self.B.pop()
        if not self.A:
            return -1
        else:
            while self.A:
                self.B.append(self.A.pop())
            return self.B.pop()




# Your CQueue object will be instantiated and called as such:
# obj = CQueue()
# obj.appendTail(value)
# param_2 = obj.deleteHead()

剑指 Offer 30. 包含min函数的栈

class MinStack:

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


    def push(self, x: int) -> None:
        self.A.append(x)
        if not self.B or self.B[-1]>=x:
            self.B.append(x)


    def pop(self) -> None:
        if self.A.pop() == self.B[-1]:
            self.B.pop()


    def top(self) -> int:
        return self.A[-1]
        
    def min(self) -> int:
        return self.B[-1]



# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.min()

链表(简单)

2022/2/24

剑指 Offer 06. 从尾到头打印链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        stack = []
        while head:
            stack.append(head.val)
            head = head.next
        return stack[::-1]


作者:jyd
链接:https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/solution/mian-shi-ti-06-cong-wei-dao-tou-da-yin-lian-biao-d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution:
    def reversePrint(self, head: ListNode) -> List[int]:
        self.A, self.res = [], []
        p = head
        while p:
            self.A.append(p.val)
            p = p.next
        while self.A:
            self.res.append(self.A.pop())
        return  self.res

剑指 Offer 24. 反转链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        pre, p = None, head#pre设为None,就可以一并处理了
        while p:
            after = p.next
            p.next = pre
            pre = p
            p = after
        return pre

*剑指 Offer 35. 复杂链表的复制

#哈希表法
"""
# Definition for a Node.
class Node:
    def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
        self.val = int(x)
        self.next = next
        self.random = random
"""
class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        if not head:
            return head
        dic = {}
        cur = head
        while cur:
            dic[cur] = Node(cur.val)#键是原链表节点,值是新链表节点
            cur = cur.next
        cur = head
        while cur:
            dic[cur].next = dic.get(cur.next)#哈希表 get()返回指定键的值
            dic[cur].random = dic.get(cur.random)
            cur = cur.next
        return dic[head]


#拼接+拆分
class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        if not head: return
        cur = head
        # 1. 复制各节点,并构建拼接链表
        while cur:
            tmp = Node(cur.val)
            tmp.next = cur.next
            cur.next = tmp
            cur = tmp.next
        # 2. 构建各新节点的 random 指向
        cur = head
        while cur:
            if cur.random:
                cur.next.random = cur.random.next
            cur = cur.next.next
        # 3. 拆分两链表
        cur = res = head.next
        pre = head
        while cur.next:
            pre.next = pre.next.next
            cur.next = cur.next.next
            pre = pre.next
            cur = cur.next
        pre.next = None # 单独处理原链表尾节点
        return res      # 返回新链表头节点


作者:jyd
链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/solution/jian-zhi-offer-35-fu-za-lian-biao-de-fu-zhi-ha-xi-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

字符串(简单)

剑指 Offer 05. 替换空格

class Solution:
    def replaceSpace(self, s: str) -> str:
        res = []
        for c in s:
            if c == " ":
                res.append("%20")
            else:
                res.append(c)
        return "".join(res)

剑指 Offer 58 - II. 左旋转字符串

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        A = []
        for c in s:
            A.append(c)
        for i in range(n):
            tmp = A.pop(0)
            A.append(tmp)
        return "".join(A)
#字符串切片
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        res = []
        for i in range(n, len(s)):
            res.append(s[i])
        for i in range(n):
            res.append(s[i])
        return ''.join(res)


作者:jyd
链接:https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/solution/mian-shi-ti-58-ii-zuo-xuan-zhuan-zi-fu-chuan-qie-p/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        return s[n:] + s[:n]


作者:jyd
链接:https://leetcode-cn.com/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/solution/mian-shi-ti-58-ii-zuo-xuan-zhuan-zi-fu-chuan-qie-p/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

查找算法(简单)

2022/2/26

剑指 Offer 03. 数组中重复的数字

class Solution:
    def findRepeatNumber(self, nums: List[int]) -> int:
        dic = {}
        for n in nums:
            if not dic.get(n): 
                dic[n] = 1
            else:return n

class Solution:
    def findRepeatNumber(self, nums: [int]) -> int:
        dic = set()
        for num in nums:
            if num in dic: return num
            dic.add(num)
        return -1


作者:jyd
链接:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solution/mian-shi-ti-03-shu-zu-zhong-zhong-fu-de-shu-zi-yua/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 53 - I. 在排序数组中查找数字 I

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        dic = {}
        for n in nums:
            if not dic.get(n):
                dic[n] = 1
            else:
                dic[n]+=1
        if dic.get(target):
            return dic.get(target)
        else:
            return 0
#找target 和 target-1的右边界相减
class Solution:
    def search(self, nums: [int], target: int) -> int:
        def helper(tar):
            i, j = 0, len(nums) - 1
            while i <= j:
                m = (i + j) // 2
                if nums[m] <= tar: i = m + 1
                else: j = m - 1
            return i
        return helper(target) - helper(target - 1)


作者:jyd
链接:https://leetcode-cn.com/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/solution/mian-shi-ti-53-i-zai-pai-xu-shu-zu-zhong-cha-zha-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 53 - II. 0~n-1中缺失的数字

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        i, j = 0, len(nums)
        if nums[i]:
            return 0
        if j-1 == nums[j-1]:
            return j
        while i<=j:
            mid = int((i+j)/2)
            if mid == nums[mid] and mid+1 <nums[mid+1]:
                return mid+1
            elif mid < nums[mid]: 
                j = mid-1
                
            elif mid == nums[mid]:
                i = mid+1
class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        i, j = 0, len(nums) - 1
        while i <= j:
            m = (i + j) // 2
            if nums[m] == m: i = m + 1
            else: j = m - 1
        return i


作者:jyd
链接:https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/solution/mian-shi-ti-53-ii-0n-1zhong-que-shi-de-shu-zi-er-f/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

查找算法(中等)

2022/2/27

* 剑指 Offer 04. 二维数组中的查找

#从矩阵 matrix 左下角元素(索引设为 (i, j) )开始遍历,并与目标值对比:
#当matrix[i][j] > target时,执行i-- ,即消去第 i 行元素;
#当matrix[i][j] < target时,执行j++ ,即消去第 j 列元素;
#当matrix[i][j] = target时,返回true,代表找到目标值。

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        i, j = len(matrix) - 1, 0
        while i >= 0 and j < len(matrix[0]):
            if matrix[i][j] > target: i -= 1
            elif matrix[i][j] < target: j += 1
            else: return True
        return False


作者:jyd
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/solution/mian-shi-ti-04-er-wei-shu-zu-zhong-de-cha-zhao-zuo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 11. 旋转数组的最小数字

class Solution:
    def minArray(self, numbers: [int]) -> int:
        i, j = 0, len(numbers) - 1
        while i < j:
            m = (i + j) // 2
            if numbers[m] > numbers[j]: i = m + 1
            elif numbers[m] < numbers[j]: j = m
            else: j -= 1
        return numbers[i]


作者:jyd
链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/solution/mian-shi-ti-11-xuan-zhuan-shu-zu-de-zui-xiao-shu-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
    def minArray(self, numbers: List[int]) -> int:
        i, j, min = 0, len(numbers)-1, numbers[-1]
        while i<len(numbers) and j>=0 and i<=j:
            print(i,j)
            if numbers[i] > numbers[j]:
                i+=1
            elif numbers[i] <= numbers[j]:
                min = numbers[i]
                if j>i:
                    j-=1
                else :return min
        return min

剑指 Offer 50. 第一个只出现一次的字符

class Solution:
    def firstUniqChar(self, s: str) -> str:
        dic = {}
        for c in s:
            dic[c] = not c in dic
        for c in s:
            if dic[c]: return c
        return ' '


作者:jyd
链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/mian-shi-ti-50-di-yi-ge-zhi-chu-xian-yi-ci-de-zi-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#有序哈希表
class Solution:
    def firstUniqChar(self, s: str) -> str:
        dic = collections.OrderedDict()
        for c in s:
            dic[c] = not c in dic
        for k, v in dic.items():
            if v: return k
        return ' '


作者:jyd
链接:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/solution/mian-shi-ti-50-di-yi-ge-zhi-chu-xian-yi-ci-de-zi-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
    def firstUniqChar(self, s: str) -> str:
        dic = {}
        for c in s:
            if not dic.get(c):
                dic[c] = 1
            else:
                dic[c] = dic[c]+1
        for c in s:
            if dic[c]:
                return c
        return " "

搜索与回溯算法(简单)

2022/2/28

面试题32 - I. 从上到下打印二叉树

#队列
class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        if not root: return []
        res, queue = [], collections.deque()
        queue.append(root)
        while queue:
            node = queue.popleft()
            res.append(node.val)
            if node.left: queue.append(node.left)
            if node.right: queue.append(node.right)
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/solution/mian-shi-ti-32-i-cong-shang-dao-xia-da-yin-er-ch-4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 32 - II. 从上到下打印二叉树 II

复杂度分析:

时间复杂度 O(N) : N 为二叉树的节点数量,即 BFS 需循环 N 次。
空间复杂度 O(N) : 最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N)大小的额外空间。
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        res, queue = [], collections.deque()
        queue.append(root)
        while queue:
            tmp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                tmp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            res.append(tmp)
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/solution/mian-shi-ti-32-ii-cong-shang-dao-xia-da-yin-er-c-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        res, que = [], collections.deque()
        que.append(root)
        while que:
            tmp,out = [],[]
            while que:
                node = que.popleft()                 
                tmp.append(node.val)
                out.append(node)
            res.append(tmp)
            for node in out:
                if node.left: que.append(node.left)
                if node.right: que.append(node.right)
        return res

剑指 Offer 32 - III. 从上到下打印二叉树 III

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        res, deque = [], collections.deque([root])
        while deque:
            tmp = collections.deque()
            for _ in range(len(deque)):
                node = deque.popleft()
                if len(res) % 2: tmp.appendleft(node.val) # 偶数层 -> 队列头部
                else: tmp.append(node.val) # 奇数层 -> 队列尾部
                if node.left: deque.append(node.left)
                if node.right: deque.append(node.right)
            res.append(list(tmp))
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er--3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
方法三:层序遍历 + 倒序

    此方法的优点是只用列表即可,无需其他数据结构。
    偶数层倒序: 若 res 的长度为 奇数 ,说明当前是偶数层,则对 tmp 执行 倒序 操作。


class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root: return []
        res, queue = [], collections.deque()
        queue.append(root)
        while queue:
            tmp = []
            for _ in range(len(queue)):
                node = queue.popleft()
                tmp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            res.append(tmp[::-1] if len(res) % 2 else tmp)
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/solution/mian-shi-ti-32-iii-cong-shang-dao-xia-da-yin-er--3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if not root:
            return []
        res, que = [], collections.deque()
        que.append(root)
        flag = False
        while que:
            tmp = []  
            for i in range(len(que)):
                node = que.popleft()
                tmp.append(node.val)
                if node.left:
                    que.append(node.left)
                if node.right:
                    que.append(node.right)
            if flag:
                res.append(tmp[::-1])     
            else:
                res.append(tmp)
            flag = not flag
        return res

搜索与回溯(简单)

2020\03\01

* 递归-剑指 Offer 26. 树的子结构

recur(A, B) 函数:

1、终止条件:
当节点 B 为空:说明树 B已匹配完成(越过叶子节点),因此返回 true ;
当节点 A为空:说明已经越过树 A 叶子节点,即匹配失败,返回 false ;
当节点 A 和 B 的值不同:说明匹配失败,返回 false ;
2、 返回值:
判断 A 和 B 的左子节点是否相等,即 recur(A.left, B.left)
判断 A 和 B的右子节点是否相等,即 recur(A.right, B.right)

isSubStructure(A, B) 函数:

特例处理: 当 树 A为空 或 树 B 为空 时,直接返回 false ;
返回值: 若树 B是树 A 的子结构,则必满足以下三种情况之一,因此用或 || 连接;
以 节点 A 为根节点的子树 包含树 B ,对应 recur(A, B);
树 B 是 树 A左子树 的子结构,对应 isSubStructure(A.left, B);
树 B是 树 A右子树 的子结构,对应 isSubStructure(A.right, B);

class Solution:
    def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
        def recur(A, B):
            if not B: return True
            if not A or A.val != B.val: return False
            return recur(A.left, B.left) and recur(A.right, B.right)

        return bool(A and B) and (recur(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B))


作者:jyd
链接:https://leetcode-cn.com/problems/shu-de-zi-jie-gou-lcof/solution/mian-shi-ti-26-shu-de-zi-jie-gou-xian-xu-bian-li-p/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

* 递归-剑指 Offer 27. 二叉树的镜像

方法一:递归法

根据二叉树镜像的定义,考虑递归遍历(dfs)二叉树,交换每个节点的左 / 右子节点,即可生成二叉树的镜像。

递归解析:

1.终止条件 当节点 root为空时(即越过叶节点),则返回 null ;

2.递推工作

1.初始化节点 tmp ,用于暂存 root 的左子节点;

2.开启递归 右子节点 mirrorTree(root.right),并将返回值作为 root的 左子节点 。

3.开启递归 左子节点 mirrorTree(tmp) ,并将返回值作为 root的 右子节点 。

3.返回值: 返回当前节点 root ;

Q: 为何需要暂存 root的左子节点?

A: 在递归右子节点 “root.left=mirrorTree(root.right);” 执行完毕后, root.left 的值已经发生改变,此时递归左子节点 mirrorTree(root.left)则会出问题。

#时间复杂度 O(N): 其中 N为二叉树的节点数量,建立二叉树镜像需要遍历树的所有节点,占用 O(N) 时间。
#空间复杂度 O(N) : 最差情况下(当二叉树退化为链表),递归时系统需使用 O(N) 大小的栈空间。


class Solution:
    def mirrorTree(self, root: TreeNode) -> TreeNode:
        if not root: return
        tmp = root.left
        root.left = self.mirrorTree(root.right)
        root.right = self.mirrorTree(tmp)
        return root

作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#Python 利用平行赋值的写法(即 a,b=b,a ),可省略暂存操作。其原理是先将等号右侧打包成元组 (b,a) ,再序列地分给等号左侧的 a,b 序列。

class Solution:
    def mirrorTree(self, root: TreeNode) -> TreeNode:
        if not root: return
        root.left, root.right = self.mirrorTree(root.right), self.mirrorTree(root.left)
        return root

作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法二:辅助栈(或队列)

利用栈(或队列)遍历树的所有节点 node,并交换每个 node 的左 / 右子节点。

算法流程:

1.特例处理: 当 root 为空时,直接返回 null;
2.初始化: 栈(或队列),本文用栈,并加入根节点 root 。
3.循环交换: 当栈 stack 为空时跳出;
1.出栈: 记为 node ;
2.添加子节点: 将 node 左和右子节点入栈;
3.交换: 交换 node 的左 / 右子节点。
4.返回值: 返回根节点 root 。

#复杂度分析:

  #  时间复杂度 O(N) : 其中 N 为二叉树的节点数量,建立二叉树镜像需要遍历树的所有节点,占用 O(N)时间。
   # 空间复杂度 O(N) : 最差情况下(右子树都为叶结点),栈 stack最多同时存储 2^(N+1) 个节点,占用 O(N) 额外空间。
class Solution:
    def mirrorTree(self, root: TreeNode) -> TreeNode:
        if not root: return
        stack = [root]
        while stack:
            node = stack.pop()
            if node.left: stack.append(node.left)
            if node.right: stack.append(node.right)
            node.left, node.right = node.right, node.left
        return root


作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof/solution/mian-shi-ti-27-er-cha-shu-de-jing-xiang-di-gui-fu-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

* 递归-剑指 Offer 28. 对称的二叉树

对称二叉树定义: 对于树中 任意两个对称节点 L和 R ,一定有:

L.val=R.val :即此两对称节点值相等。
L.left.val=R.right.val :即 L 的 左子节点 和 R 的 右子节点 对称;
L.right.val=R.left.val :即 L 的 右子节点 和 R的 左子节点 对称。

算法流程:

isSymmetric(root) :

​ 特例处理: 若根节点 root 为空,则直接返回 true 。
​ 返回值: 即 recur(root.left, root.right) ;

recur(L, R)

终止条件:
当 L和 R 同时越过叶节点: 此树从顶至底的节点都对称,因此返回 true ;
当 L 或 R 中只有一个越过叶节点: 此树不对称,因此返回 false ;
当节点 L 值 ≠ 节点 R 值: 此树不对称,因此返回 falsee ;
递推工作:
判断两节点 L.lef 和 R.right是否对称,即 recur(L.left, R.right) ;
判断两节点 L.right 和 R.left 是否对称,即 recur(L.right, R.left) ;
返回值:

两对节点都对称时,才是对称树,因此用与逻辑符 && 连接。

class Solution:
    def isSymmetric(self, root: TreeNode) -> bool:
        def recur(L, R):
            if not L and not R: return True
            if not L or not R or L.val != R.val: return False
            return recur(L.left, R.right) and recur(L.right, R.left)

        return recur(root.left, root.right) if root else True


作者:jyd
链接:https://leetcode-cn.com/problems/dui-cheng-de-er-cha-shu-lcof/solution/mian-shi-ti-28-dui-cheng-de-er-cha-shu-di-gui-qing/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

动态规划(简单)

2022/03/02

*动态规划-剑指 Offer 10- I. 斐波那契数列

此类求 多少种可能性 的题目一般都有 递推性质 ,即 f(n)f(n)f(n) 和 f(n−1)f(n-1)f(n−1)…f(1)f(1)f(1) 之间是有联系的。

动态规划解析:

状态定义: 设 dp为一维数组,其中 dp[i]的值代表 斐波那契数列第 i 个数字 。
转移方程: dp[i+1]=dp[i]+dp[i−1] ,即对应数列定义 f(n+1)=f(n)+f(n−1);
初始状态: dp[0]=0, dp[1]=1,即初始化前两个数字;
返回值: dp[n],即斐波那契数列的第 n个数字。

class Solution:
    def fib(self, n: int) -> int:
        a, b = 0, 1
        for _ in range(n):
            a, b = b, a + b
        return a % 1000000007


作者:jyd
链接:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/solution/mian-shi-ti-10-i-fei-bo-na-qi-shu-lie-dong-tai-gui/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 10- II. 青蛙跳台阶问题

青蛙跳台阶问题: f(0)=1 , f(1)=1 , f(2)=2 ;#因为F(2)=2,所以f(0)=1
斐波那契数列问题: f(0)=0 , f(1)=1 , f(2)=1 。

class Solution:
    def numWays(self, n: int) -> int:
        a, b = 1, 1
        for _ in range(n):
            a, b = b, a + b
        return a % 1000000007


作者:jyd
链接:https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/solution/mian-shi-ti-10-ii-qing-wa-tiao-tai-jie-wen-ti-dong/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 63. 股票的最大利润

动态规划解析

状态定义: 设动态规划列表 dp ,dp[i] 代表以 prices[i] 为结尾的子数组的最大利润(以下简称为 前 i 日的最大利润 )。
转移方程: 由于题目限定 “买卖该股票一次” ,因此前 i日最大利润 dp[i]等于前 i−1日最大利润 dp[i−1]和第 i 日卖出的最大利润中的最大值。

前i日最大利润=max⁡(前(i−1)日最大利润,第i日价格−前i日最低价格)

dp[i]=max⁡(dp[i−1],prices[i]−min⁡(prices[0:i]))

初始状态: dp[0]=0,即首日利润为 0 ;
返回值: dp[n−1] ,其中 n为 dp 列表长度。

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        cost, profit = float("+inf"), 0
        for price in prices:
            cost = min(cost, price)
            profit = max(profit, price - cost)
        return profit


作者:jyd
链接:https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/solution/mian-shi-ti-63-gu-piao-de-zui-da-li-run-dong-tai-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

动态规划(中等)

2022/03/03

剑指 Offer 42. 连续子数组的最大和

转移方程: 若 dp[i−1]≤0 ,说明 dp[i−1] 对 dp[i]产生负贡献,即 dp[i−1]+nums[i] 还不如 nums[i] 本身大。

当 dp[i−1]>0 时:执行 dp[i]=dp[i−1]+nums[i];
当 dp[i−1]≤0 时:执行 dp[i]=nums[i] ;

初始状态: dp[0]=nums[0],即以 nums[0]结尾的连续子数组最大和为 nums[0] 。

返回值: 返回 dpdpdp 列表中的最大值,代表全局最大值。

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        for i in range(1, len(nums)):
            nums[i] += max(nums[i - 1], 0)
        return max(nums)


作者:jyd
链接:https://leetcode-cn.com/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/solution/mian-shi-ti-42-lian-xu-zi-shu-zu-de-zui-da-he-do-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 47. 礼物的最大价值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qUcu37we-1648863192590)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220304214354903.png)]

class Solution:
    def maxValue(self, grid: List[List[int]]) -> int:
        for i in range(len(grid)):
            for j in range(len(grid[0])):
                if i == 0 and j == 0: continue
                if i == 0: grid[i][j] += grid[i][j - 1]
                elif j == 0: grid[i][j] += grid[i - 1][j]
                else: grid[i][j] += max(grid[i][j - 1], grid[i - 1][j])
        return grid[-1][-1]


作者:jyd
链接:https://leetcode-cn.com/problems/li-wu-de-zui-da-jie-zhi-lcof/solution/mian-shi-ti-47-li-wu-de-zui-da-jie-zhi-dong-tai-gu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

动态规划(中等)

2020/3/4

剑指 Offer 46. 把数字翻译成字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VoFP6reI-1648863192590)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220306152644582.png)]

class Solution:
    def translateNum(self, num: int) -> int:
        s = str(num)
        a = b = 1
        for i in range(2, len(s) + 1):
            a, b = (a + b if "10" <= s[i - 2:i] <= "25" else a), a
        return a


作者:jyd
链接:https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/solution/mian-shi-ti-46-ba-shu-zi-fan-yi-cheng-zi-fu-chua-6/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 48. 最长不含重复字符的子字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QNcrxgKH-1648863192591)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220306164941644.png)]

#by Mallika
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        if not len(s):
            return 0
        a, b = 1, 1
        for i in range(1, len(s)):
            if s[i] in s[i-a: i]:
                a = i-s[0: i].rfind(s[i])
                b = a if a>b else b
            else: 
                a+=1
                b = a if a>b else b
        return b
class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        dic = {}
        res = tmp = 0
        for j in range(len(s)):
            i = dic.get(s[j], -1) # 获取索引 i
            dic[s[j]] = j # 更新哈希表
            tmp = tmp + 1 if tmp < j - i else j - i # dp[j - 1] -> dp[j]
            res = max(res, tmp) # max(dp[j - 1], dp[j])
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/mian-shi-ti-48-zui-chang-bu-han-zhong-fu-zi-fu-d-9/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

双指针(简单)

2022/3/6

剑指 Offer 18. 删除链表的节点

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteNode(self, head: ListNode, val: int) -> ListNode:
        pre_head = ListNode(-1)
        pre_head.next = head
        pre = pre_head
        p=pre.next
        while p:
            if p.val == val:
                pre.next = p.next
                pre = p
                p = p.next
                return pre_head.next
            else:
                pre = p
                p = p.next
        return pre_head.next

剑指 Offer 22. 链表中倒数第k个节点

#考虑越界情况
class Solution:
    def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
        former, latter = head, head
        for _ in range(k):
            if not former: return
            former = former.next
        while former:
            former, latter = former.next, latter.next
        return latter


作者:jyd
链接:https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/solution/mian-shi-ti-22-lian-biao-zhong-dao-shu-di-kge-j-11/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

双指针(简单)

2022/03/07

剑指 Offer 25. 合并两个排序的链表

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        cur = dum = ListNode(0)
        while l1 and l2:
            if l1.val < l2.val:
                cur.next, l1 = l1, l1.next
            else:
                cur.next, l2 = l2, l2.next
            cur = cur.next
        cur.next = l1 if l1 else l2
        return dum.next


作者:jyd
链接:https://leetcode-cn.com/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/solution/mian-shi-ti-25-he-bing-liang-ge-pai-xu-de-lian-b-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        head = ListNode(-1)
        p=head
        while l1 and l2:
            if l1.val <= l2.val:
                node =ListNode(l1.val)
                p.next = node
                p = p.next
                l1 = l1.next
            elif l1.val>l2.val:
                node = ListNode(l2.val)
                p.next = node
                p = p.next
                l2 = l2.next
        if l1:
            p.next = l1
        elif l2:
            p.next = l2
        return head.next

剑指 Offer 52. 两个链表的第一个公共节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tz0P3cIO-1648863192591)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220307144024241.png)]

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        A, B = headA, headB
        while A != B:
            A = A.next if A else headB
            B = B.next if B else headA
        return A


作者:jyd
链接:https://leetcode-cn.com/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/solution/jian-zhi-offer-52-liang-ge-lian-biao-de-gcruu/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#快慢指针
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
        if not headA or not headB:
            return None
        l1, l2 = 0, 0
        p1, p2 = headA, headB
        while p1:
            l1+=1
            p1 = p1.next
        while p2:
            l2+=1
            p2 = p2.next
        p1, p2 = headA, headB
        if l1>=l2:
            tmp = l1-l2
            while tmp and p1:
                tmp-=1
                p1 = p1.next
        else:
            tmp = l2-l1
            while tmp and p2:
                tmp-=1
                p2 = p2.next
        while p1 and p2:
            if p1==p2:
                return p1
            else:
                p1 = p1.next
                p2 = p2.next
        return None

剑指 Offer 21. 调整数组顺序使奇数位于偶数前面

#快排
class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        i, j = 0, len(nums) - 1
        while i < j:
            while i < j and nums[i] & 1 == 1: i += 1
            while i < j and nums[j] & 1 == 0: j -= 1
            nums[i], nums[j] = nums[j], nums[i]
        return nums


作者:jyd
链接:https://leetcode-cn.com/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/solution/mian-shi-ti-21-diao-zheng-shu-zu-shun-xu-shi-qi-4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        l = len(nums)
        left, right = 0, l-1
        while left<right:
            while left<right and nums[left]%2==1:
                left+=1
            while right>left and nums[right]%2==0:
                right-=1
            tmp = nums[left]
            nums[left] = nums[right]
            nums[right] = tmp
            left += 1
            right -= 1
        return nums

剑指 Offer 57. 和为s的两个数字

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        i, j = 0, len(nums) - 1
        while i < j:
            s = nums[i] + nums[j]
            if s > target: j -= 1
            elif s < target: i += 1
            else: return nums[i], nums[j]
        return []


作者:jyd
链接:https://leetcode-cn.com/problems/he-wei-sde-liang-ge-shu-zi-lcof/solution/mian-shi-ti-57-he-wei-s-de-liang-ge-shu-zi-shuang-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        i, j = 0, len(nums)-1
        while i<=len(nums)-1 and j>=0:
            if nums[i]+nums[j]==target: return [nums[i], nums[j]]
            elif nums[i]+nums[j]>target: j-=1
            else: i+=1
        return []

剑指 Offer 58 - I. 翻转单词顺序

#切片反转
class Solution:
    def reverseWords(self, s: str) -> str:
        ch = s.split(" ")
        res = ""
        for c in ch[::-1]:
            if c != "":
                res = res+c+" "
            else: continue
        return res[:-1]
#切割翻转
class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip() # 删除首尾空格
        strs = s.split() # 分割字符串
        strs.reverse() # 翻转单词列表
        return ' '.join(strs) # 拼接为字符串并返回
class Solution:
    def reverseWords(self, s: str) -> str:
        return ' '.join(s.strip().split()[::-1])

作者:jyd
链接:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/mian-shi-ti-58-i-fan-zhuan-dan-ci-shun-xu-shuang-z/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#倒序遍历
class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip() # 删除首尾空格
        i = j = len(s) - 1
        res = []
        while i >= 0:
            while i >= 0 and s[i] != ' ': i -= 1 # 搜索首个空格
            res.append(s[i + 1: j + 1]) # 添加单词
            while s[i] == ' ': i -= 1 # 跳过单词间空格
            j = i # j 指向下个单词的尾字符
        return ' '.join(res) # 拼接并返回


作者:jyd
链接:https://leetcode-cn.com/problems/fan-zhuan-dan-ci-shun-xu-lcof/solution/mian-shi-ti-58-i-fan-zhuan-dan-ci-shun-xu-shuang-z/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

搜索与回溯算法(中等)

剑指 Offer 12. 矩阵中的路径

典型的矩阵搜索问题,可使用深度优先搜索(DFS)+剪枝解决:

深度优先搜索: 可以理解为暴力法遍历矩阵中所有字符串可能性。DFS 通过递归,先朝一个方向搜到底,再回溯至上个节点,沿另一个方向搜索,以此类推。
剪枝: 在搜索中,遇到 这条路不可能和目标字符串匹配成功 的情况(例如:此矩阵元素和目标字符不同、此元素已被访问),则应立即返回,称之为 可行性剪枝 。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J8AgkRe8-1648863192592)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220308142432780.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SvjhvXsL-1648863192592)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220308142513261.png)]

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        def dfs(i, j, k):
            if not 0 <= i < len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]: return False
            if k == len(word) - 1: return True
            board[i][j] = ''
            res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)
            board[i][j] = word[k]
            return res

        for i in range(len(board)):
            for j in range(len(board[0])):
                if dfs(i, j, 0): return True
        return False


作者:jyd
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/mian-shi-ti-12-ju-zhen-zhong-de-lu-jing-shen-du-yo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 13. 机器人的运动范围

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YHseBfgl-1648863192593)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220308151655309.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XO0WiTPH-1648863192594)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220308152105533.png)]

class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        def dfs(i, j, si, sj):
            if i >= m or j >= n or k < si + sj or (i, j) in visited: return 0
            visited.add((i,j))
            return 1 + dfs(i + 1, j, si + 1 if (i + 1) % 10 else si - 8, sj) + dfs(i, j + 1, si, sj + 1 if (j + 1) % 10 else sj - 8)

        visited = set()
        return dfs(0, 0, 0, 0)


作者:jyd
链接:https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/solution/mian-shi-ti-13-ji-qi-ren-de-yun-dong-fan-wei-dfs-b/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
    def movingCount(self, m: int, n: int, k: int) -> int:
        visit = [[0]*n for row in range(m)] 
        count = 0
        def sums(x):
            s = 0
            while x!=0:
                s += x%10
                x = x//10
            return s

        def dfs(i, j):
            if sums(i)+sums(j) > k or not 0<=i<m or not 0<=j<n or visit[i][j]:
                print(sums(i)+sums(j))
                return 0
            print(i,j)
            visit[i][j] = 1
            return 1+dfs(i+1, j) + dfs(i, j+1)
        return dfs(0,0)

剑指 Offer 34. 二叉树中和为某一值的路径

解题思路:

本问题是典型的二叉树方案搜索问题,使用回溯法解决,其包含 先序遍历 + 路径记录 两部分。

先序遍历: 按照 “根、左、右” 的顺序,遍历树的所有节点。
路径记录: 在先序遍历中,记录从根节点到当前节点的路径。当路径为 ① 根节点到叶节点形成的路径 且 ② 各节点值的和等于目标值 sum 时,将此路径加入结果列表。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aEqIXmIV-1648863192594)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309130931543.png)]

class Solution:
    def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
        res, path = [], []
        def recur(root, tar):
            if not root: return
            path.append(root.val)
            tar -= root.val
            if tar == 0 and not root.left and not root.right:
                res.append(list(path))
            recur(root.left, tar)
            recur(root.right, tar)
            path.pop()

        recur(root, sum)
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/solution/mian-shi-ti-34-er-cha-shu-zhong-he-wei-mou-yi-zh-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0tlTXd8Q-1648863192595)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309133325242.png)]

剑指 Offer 36. 二叉搜索树与双向链表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AB97BdcP-1648863192596)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309151353146.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aoYvgqr8-1648863192596)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309153342851.png)]

class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        def dfs(cur):
            if not cur: return
            dfs(cur.left) # 递归左子树
            if self.pre: # 修改节点引用
                self.pre.right, cur.left = cur, self.pre
            else: # 记录头节点
                self.head = cur
            self.pre = cur # 保存 cur
            dfs(cur.right) # 递归右子树
        
        if not root: return
        self.pre = None
        dfs(root)
        self.head.left, self.pre.right = self.pre, self.head
        return self.head


作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/solution/mian-shi-ti-36-er-cha-sou-suo-shu-yu-shuang-xian-5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 54. 二叉搜索树的第k大节点

本文解法基于此性质:二叉搜索树的中序遍历为 递增序列 。

根据以上性质,易得二叉搜索树的 中序遍历倒序 为 递减序列 。
因此,求 “二叉搜索树第 kkk 大的节点” 可转化为求 “此树的中序遍历倒序的第 kkk 个节点”。

中序遍历 为 “左、根、右” 顺序

中序遍历的倒序 为 “右、根、左” 顺序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f3wfIJRJ-1648863192597)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220309164751245.png)]

class Solution:
    def kthLargest(self, root: TreeNode, k: int) -> int:
        def dfs(root):
            if not root: return
            dfs(root.right)
            if self.k == 0: return
            self.k -= 1
            if self.k == 0: self.res = root.val
            dfs(root.left)

        self.k = k
        dfs(root)
        return self.res


作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/solution/mian-shi-ti-54-er-cha-sou-suo-shu-de-di-k-da-jie-d/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
    def kthLargest(self, root: TreeNode, k: int) -> int:
        que = []
        def dfs(cur):
            if not cur: return
            dfs(cur.left)
            que.append(cur.val)
            dfs(cur.right)
        
        if not root: return None
        dfs(root)
        print(que)
        return que[-k]

2022/3/10

python数据类型

不可变数据类型: 当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,就称不可变数据类型。

**可变数据类型 :**当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变,对于这种数据类型,就称可变数据类型。

数据类型 可变/不可变
整型 不可变
字符串 不可变
元组 不可变(只可读)
列表 可变
集合 可变
字典 可变

排序(简单)

剑指 Offer 45. 把数组排成最小的数

此题求拼接起来的最小数字,本质上是一个排序问题。设数组 nums中任意两数字的字符串为 x 和 y ,则规定 排序判断规则 为:

若拼接字符串 x+y>y+x ,则 x “大于” y ;
反之,若 x+y

class Solution:
    def minNumber(self, nums: List[int]) -> str:
        def quick_sort(l , r):
            if l >= r: return
            i, j = l, r
            while i < j:
                while strs[j] + strs[l] >= strs[l] + strs[j] and i < j: j -= 1
                while strs[i] + strs[l] <= strs[l] + strs[i] and i < j: i += 1
                strs[i], strs[j] = strs[j], strs[i]
            strs[i], strs[l] = strs[l], strs[i]
            quick_sort(l, i - 1)
            quick_sort(i + 1, r)
        
        strs = [str(num) for num in nums]
        quick_sort(0, len(strs) - 1)
        return ''.join(strs)


作者:jyd
链接:https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/solution/mian-shi-ti-45-ba-shu-zu-pai-cheng-zui-xiao-de-s-4/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class Solution:
    def minNumber(self, nums: List[int]) -> str:
        for i in range(len(nums)):
            for j in range(0, len(nums)):
                if str(nums[i])+str(nums[j])<str(nums[j])+str(nums[i]):
                    nums[i],nums[j] = nums[j], nums[i]
        print(nums)
        res = "".join(str(n) for n in nums)
        return res

剑指 Offer 61. 扑克牌中的顺子

class Solution:
    def isStraight(self, nums: List[int]) -> bool:
        repeat = set()
        ma, mi = 0, 14
        for num in nums:
            if num == 0: continue # 跳过大小王
            ma = max(ma, num) # 最大牌
            mi = min(mi, num) # 最小牌
            if num in repeat: return False # 若有重复,提前返回 false
            repeat.add(num) # 添加牌至 Set
        return ma - mi < 5 # 最大牌 - 最小牌 < 5 则可构成顺子 


作者:jyd
链接:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/solution/mian-shi-ti-61-bu-ke-pai-zhong-de-shun-zi-ji-he-se/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

class Solution:
    def isStraight(self, nums: List[int]) -> bool:
        joker = 0
        nums.sort() # 数组排序
        for i in range(4):
            if nums[i] == 0: joker += 1 # 统计大小王数量
            elif nums[i] == nums[i + 1]: return False # 若有重复,提前返回 false
        return nums[4] - nums[joker] < 5 # 最大牌 - 最小牌 < 5 则可构成顺子


作者:jyd
链接:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/solution/mian-shi-ti-61-bu-ke-pai-zhong-de-shun-zi-ji-he-se/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

排序(中等)

剑指 Offer 40. 最小的k个数

#快排
class Solution:
    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        def quick_sort(arr, l, r):
            if l>=r: return
            i, j = l, r
            while i<j: 
                while i<j and arr[j]>=arr[l]: j-=1
                while i<j and arr[i]<=arr[l]: i+=1  
                arr[i], arr[j] = arr[j], arr[i]                   
            arr[l], arr[i] = arr[i], arr[l]
            quick_sort(arr, l, i-1)
            quick_sort(arr,i+1, r)
        quick_sort(arr, 0, len(arr)-1)
        return arr[:k]

剑指 Offer 41. 数据流中的中位数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qfUIRGKj-1648863192597)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220311153752546.png)]

from heapq import *

class MedianFinder:
    def __init__(self):
        self.A = [] # 小顶堆,保存较大的一半
        self.B = [] # 大顶堆,保存较小的一半

    def addNum(self, num: int) -> None:
        if len(self.A) != len(self.B):
            heappush(self.B, -heappushpop(self.A, num))
        else:
            heappush(self.A, -heappushpop(self.B, -num))

    def findMedian(self) -> float:
        return self.A[0] if len(self.A) != len(self.B) else (self.A[0] - self.B[0]) / 2.0


作者:jyd
链接:https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/solution/mian-shi-ti-41-shu-ju-liu-zhong-de-zhong-wei-shu-y/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#by Mallika
class MedianFinder:
    def __init__(self):
        """
        initialize your data structure here.
        """
        self.nums = []
        self.length = 0

    def addNum(self, num: int) -> None:
        if not self.length:
            self.nums.append(num)
            self.length+=1
        else:
            pos=0
            while pos<self.length and self.nums[pos]<=num:
                pos+=1
            self.nums.insert(pos, num)
            self.length+=1
        return

    def findMedian(self) -> float:
        if self.length==0: return self.nums
        elif self.length==1: return self.nums[0]
        elif self.length % 2:
            return self.nums[int(self.length/2)]
        else:
            return (self.nums[int((self.length-1)/2)]+self.nums[int((self.length-1)/2)+1])/
        

搜索与回溯算法(中等)

*剑指 Offer 55 - I. 二叉树的深度

class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root: return 0
        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/mian-shi-ti-55-i-er-cha-shu-de-shen-du-xian-xu-bia/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#层次遍历
class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root: return 0
        queue, res = [root], 0
        while queue:
            tmp = []
            for node in queue:
                if node.left: tmp.append(node.left)
                if node.right: tmp.append(node.right)
            queue = tmp
            res += 1
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/mian-shi-ti-55-i-er-cha-shu-de-shen-du-xian-xu-bia/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#by Mallika
class Solution:
    def maxDepth(self, root: TreeNode) -> int:
        if not root: return 0
        que = collections.deque()
        que.append(root)
        res = 0
        tmp = []
        while que:
            node = que.popleft()
            # print(node.val)
            if node.left: tmp.append(node.left)
            if node.right: tmp.append(node.right)
            if not len(que):
                res+=1
                for t in tmp:
                    que.append(t)
                tmp = []

* 剑指 Offer 55 - II. 平衡二叉树

以下两种方法均基于以下性质推出: 此树的深度 等于 左子树的深度右子树的深度 中的 最大值 +1 。

方法一: 后序遍历+剪枝(从底至顶)

思路是对二叉树做后序遍历,从底至顶返回子树深度,若判定某子树不是平衡树则 “剪枝” ,直接向上返回。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6UHhIcV1-1648863192598)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312145701120.png)]

#后序遍历+剪枝
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def recur(root):
            if not root: return 0
            left = recur(root.left)
            if left == -1: return -1
            right = recur(root.right)
            if right == -1: return -1
            return max(left, right) + 1 if abs(left - right) <= 1 else -1

        return recur(root) != -1


作者:jyd
链接:https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/solution/mian-shi-ti-55-ii-ping-heng-er-cha-shu-cong-di-zhi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#先序遍历+判断深度
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        if not root: return True
        return abs(self.depth(root.left) - self.depth(root.right)) <= 1 and \
            self.isBalanced(root.left) and self.isBalanced(root.right)

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

作者:jyd
链接:https://leetcode-cn.com/problems/ping-heng-er-cha-shu-lcof/solution/mian-shi-ti-55-ii-ping-heng-er-cha-shu-cong-di-zhi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

#Mallika
class Solution:
    def isBalanced(self, root: TreeNode) -> bool:
        def maxDepth(root):
            if not root: return 0 
            return max(maxDepth(root.left), maxDepth(root.right))+1
        def maxDiff(root):
            if not root: return True
            que = []
            que.append(root)
            while que:
                node = que.pop()
                if maxDepth(node.left)-maxDepth(node.right)!=0 and maxDepth(node.left)-maxDepth(node.right)!=1 and maxDepth(node.left)-maxDepth(node.right)!=-1:
                    return False
                if node.left: que.append(node.left)
                if node.right: que.append(node.right)
            return True

搜索与回溯算法

*剑指 Offer 64. 求1+2+…+n

逻辑运算解答

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aFqn2nww-1648863192599)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313105447722.png)]

class Solution:
    def __init__(self):
        self.res = 0
    def sumNums(self, n: int) -> int:
        n>1 and self.sumNums(n-1)
        self.res+=n
        return self.res

复杂度分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wDGh8o5U-1648863192599)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313110154167.png)]

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

最近公共祖先的定义: 设节点 root 为节点 p,q 的某公共祖先,若其左子节点 root.left 和右子节点 root.right 都不是 p,q 的公共祖先,则称 root 是 “最近的公共祖先” 。

根据以上定义,若 root 是 p,q 的 最近公共祖先 ,则只可能为以下情况之一:

p 和 q 在 root 的子树中,且分列 roott的 异侧(即分别在左、右子树中);
p=root,且 q 在 roott 的左或右子树中;
q=root,且 p 在 root 的左或右子树中;

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kpnzn2RT-1648863192600)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313113039265.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BaRHYIUo-1648863192600)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313113105821.png)]

#迭代
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if p.val>q.val: p, q = q, p
        while root:
            if not root: return root
            elif root.val < p.val: root = root.right
            elif root.val > q.val: root = root.left
            else: break
        return root

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u2p5E2j1-1648863192601)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313114105613.png)]

#递归
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if root.val < p.val and root.val < q.val:
            return self.lowestCommonAncestor(root.right, p, q)
        if root.val > p.val and root.val > q.val:
            return self.lowestCommonAncestor(root.left, p, q)
        return root


作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/mian-shi-ti-68-i-er-cha-sou-suo-shu-de-zui-jin-g-7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分治法

剑指 Offer 68 - I. 二叉搜索树的最近公共祖先

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JWpis3co-1648863192602)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313152746920.png)]

class Solution:
    def lowestCommonAncestor(self, root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
        if not root or root == p or root == q: return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if not left and not right: return # 1.
        if not left: return right # 3.
        if not right: return left # 4.
        return root # 2. if left and right:


作者:jyd
链接:https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/solution/mian-shi-ti-68-ii-er-cha-shu-de-zui-jin-gong-gon-7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mEobju4N-1648863192603)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220313152757198.png)]

剑指 Offer 16. 数值的整数次方

快速幂法:

"二分法", "二进制"

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-koXKmw7F-1648863192603)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314111711167.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jhCeEOXO-1648863192604)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314112048891.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Yoh9zN58-1648863192604)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314112102195.png)]

时间复杂度空间复杂度

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F7Oa2TDI-1648863192605)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314112120087.png)]

class Solution:
    def myPow(self, x: float, n: int) -> float:
        if x == 0: return 0
        res = 1
        if n < 0: x, n = 1 / x, -n
        while n:
            if n & 1: res *= x
            x *= x
            n >>= 1
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/solution/mian-shi-ti-16-shu-zhi-de-zheng-shu-ci-fang-kuai-s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 33. 二叉搜索树的后序遍历序列


位运算(简单)

剑指 Offer 15. 二进制中1的个数

def hammingWeighted(self, n:int)->int:
	res=0
	while n:
        #res += n&1
        n>>=1
		res+=1
        n&=(n-1)
        
	return res

剑指 Offer 65. 不用加减乘除做加法

a(i) b(i) 无进位和n(i) 进位和(i+1)
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1

无进位和异或运算 规律相同,进位与运算 规律相同(并需左移一位)。

非进位和:异或运算进位:n=a⊕b

与运算+左移一位: c=a&b<<1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VNekGoSa-1648863192605)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220317222312585.png)]

class Solution:
    def add(self, a: int, b: int) -> int:
        x = 0xffffffff
        a, b = a & x, b & x
        while b != 0:
            a, b = (a ^ b), (a & b) << 1 & x
        return a if a <= 0x7fffffff else ~(a ^ x)


作者:jyd
链接:https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

位运算(中等)

剑指 Offer 56 - I. 数组中数字出现的次数

class Solution:
    def singleNumbers(self, nums: List[int]) -> List[int]:
        x, y, n, m = 0, 0, 0, 1
        for num in nums:         # 1. 遍历异或
            n ^= num
        while n & m == 0:        # 2. 循环左移,计算 m
            m <<= 1       
        for num in nums:         # 3. 遍历 nums 分组
            if num & m: x ^= num # 4. 当 num & m != 0
            else: y ^= num       # 4. 当 num & m == 0
        return x, y              # 5. 返回出现一次的数字


作者:jyd
链接:https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/jian-zhi-offer-56-i-shu-zu-zhong-shu-zi-tykom/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

数学(简单)

数学(中等)

剑指 Offer 14- I. 剪绳子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v5KDktg2-1648863192606)(Leetcode刷题.assets/image-20220321213720186.png)]

class Solution:
    def cuttingRope(self, n: int) -> int:
        dp = [0] * (n + 1)
        dp[2] = 1
        for i in range(3, n + 1):
            for j in range(2, i):
                dp[i] = max(dp[i], max(j * (i - j), j * dp[i - j]))
        return dp[n]


作者:edelweisskoko
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/jian-zhi-offer-14-i-jian-sheng-zi-huan-s-xopj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 57 - II. 和为s的连续正数序列

双指针/数学求和公式

class Solution:
    def findContinuousSequence(self, target: int) -> List[List[int]]:
        i, j, s, res = 1, 2, 3, []
        while i < j:
            if s == target:
                res.append(list(range(i, j + 1)))
            if s >= target:
                s -= i
                i += 1
            else:
                j += 1
                s += j
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/jian-zhi-offer-57-ii-he-wei-s-de-lian-xu-t85z/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 62. 圆圈中最后剩下的数字

class Solution:
    def lastRemaining(self, n: int, m: int) -> int:
        x = 0
        for i in range(2, n + 1):
            x = (x + m) % i
        return x


作者:jyd
链接:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/jian-zhi-offer-62-yuan-quan-zhong-zui-ho-dcow/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

数据结构(中)

数组

136. 只出现一次的数字

hash表,set集合,异或

#hash
class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        dic = {}
        for n in nums:
            dic[n] = 1 if not dic.get(n) else 0
        for k in dic.keys():
            if dic[k]:res = k
        return res
   

#set
class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        s = set()
        for n in nums:
            if n not in s:s.add(n)
            else: s.remove(n)
        return s.pop()
 
#异或
class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        res = 0
        for num in nums:
            res ^= num
        return res


作者:tao-zhi-r
链接:https://leetcode-cn.com/problems/single-number/solution/ban-yuan-xiu-dao-duo-chong-yu-yan-yi-huo-zzoa/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

169. 多数元素

hash, 摩尔投票法-多数投票法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jDbVSgUY-1648863192606)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312165428719.png)]

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        count = 0
        candidate = None

        for num in nums:
            if count == 0:
                candidate = num
            count += (1 if num == candidate else -1)

        return candidate


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/majority-element/solution/duo-shu-yuan-su-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
#hash
class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        counts = collections.Counter(nums)
        return max(counts.keys(), key=counts.get)


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/majority-element/solution/duo-shu-yuan-su-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

15. 三数之和

排序+双指针

复杂度:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xThokwlz-1648863192606)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220312201539941.png)]

class Solution:
    def threeSum(self, nums: [int]) -> [[int]]:
        nums.sort()
        res, k = [], 0
        for k in range(len(nums) - 2):
            if nums[k] > 0: break # 1. because of j > i > k.
            if k > 0 and nums[k] == nums[k - 1]: continue # 2. skip the same `nums[k]`.
            i, j = k + 1, len(nums) - 1
            while i < j: # 3. double pointer
                s = nums[k] + nums[i] + nums[j]
                if s < 0:
                    i += 1
                    while i < j and nums[i] == nums[i - 1]: i += 1
                elif s > 0:
                    j -= 1
                    while i < j and nums[j] == nums[j + 1]: j -= 1
                else:
                    res.append([nums[k], nums[i], nums[j]])
                    i += 1
                    j -= 1
                    while i < j and nums[i] == nums[i - 1]: i += 1
                    while i < j and nums[j] == nums[j + 1]: j -= 1
        return res


作者:jyd
链接:https://leetcode-cn.com/problems/3sum/solution/3sumpai-xu-shuang-zhi-zhen-yi-dong-by-jyd/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分治算法(中等)

剑指 Offer 07. 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

分治法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pGe5loR2-1648863192607)(C:\Users\10143\AppData\Roaming\Typora\typora-user-images\image-20220314100621322.png)]

按照先序顺序构造节点,按照中序划分子树
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        def recur(root, left, right):
            if left > right: return                               # 递归终止
            node = TreeNode(preorder[root])                       # 建立根节点
            i = dic[preorder[root]]                               # 划分根节点、左子树、右子树
            node.left = recur(root + 1, left, i - 1)              # 开启左子树递归
            node.right = recur(i - left + root + 1, i + 1, right) # 开启右子树递归
            return node                                           # 回溯返回根节点

        dic, preorder = {}, preorder
        for i in range(len(inorder)):
            dic[inorder[i]] = i
        return recur(0, 0, len(inorder) - 1)


作者:jyd
链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-di-gui-fa-qin/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

美团

93. 复原 IP 地址

class Solution:
    def restoreIpAddresses(self, s: str) -> List[str]:
        SEG_COUNT = 4
        ans = list()
        segments = [0] * SEG_COUNT
        
        def dfs(segId: int, segStart: int):
            # 如果找到了 4 段 IP 地址并且遍历完了字符串,那么就是一种答案
            if segId == SEG_COUNT:
                if segStart == len(s):
                    ipAddr = ".".join(str(seg) for seg in segments)
                    ans.append(ipAddr)
                return
            
            # 如果还没有找到 4 段 IP 地址就已经遍历完了字符串,那么提前回溯
            if segStart == len(s):
                return

            # 由于不能有前导零,如果当前数字为 0,那么这一段 IP 地址只能为 0
            if s[segStart] == "0":
                segments[segId] = 0
                dfs(segId + 1, segStart + 1)
            
            # 一般情况,枚举每一种可能性并递归
            addr = 0
            for segEnd in range(segStart, len(s)):
                addr = addr * 10 + (ord(s[segEnd]) - ord("0"))
                if 0 < addr <= 0xFF:
                    segments[segId] = addr
                    dfs(segId + 1, segEnd + 1)
                else:
                    break
        

        dfs(0, 0)
        return ans


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/restore-ip-addresses/solution/fu-yuan-ipdi-zhi-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

46. 全排列

class Solution:
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        def backtrack(first = 0):
            # 所有数都填完了
            if first == n:  
                res.append(nums[:])
            for i in range(first, n):
                # 动态维护数组
                nums[first], nums[i] = nums[i], nums[first]
                # 继续递归填下一个数
                backtrack(first + 1)
                # 撤销操作
                nums[first], nums[i] = nums[i], nums[first]
        
        n = len(nums)
        res = []
        backtrack()
        return res


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/permutations/solution/quan-pai-lie-by-leetcode-solution-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

53. 最大子数组和

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        for i in range(len(nums)):
            if i==0: continue
            nums[i] = max(nums[i], nums[i-1]+nums[i])
        print(nums)
        return max(nums)

8. 字符串转换整数 (atoi)

import re
class Solution:
    def myAtoi(self, str: str) -> int:
        INT_MAX = 2147483647    
        INT_MIN = -2147483648
        str = str.lstrip()      #清除左边多余的空格
        num_re = re.compile(r'^[\+\-]?\d+')   #设置正则规则
        num = num_re.findall(str)   #查找匹配的内容
        num = int(*num) #由于返回的是个列表,解包并且转换成整数
        return max(min(num,INT_MAX),INT_MIN)    #返回值
class Solution:
    def myAtoi(self, s: str) -> int:
        s = s.strip()
        p = False
        if len(s)!=0:s = list(s)
        else: return 0
        if s[0] == "-" or s[0] == "+":
            count = 1
            for i in range(1,len(s)):
                if (s[i]<"0" or s[i]>"9"):break
                count+=1
            if count!=1: res = ''.join(s[:count])
            else:return 0
        elif s[0]>="0" and s[0]<="9":
            count = 0
            for i in range(len(s)):
                if (s[i]<"0" or s[i]>"9"):break
                count+=1
            res = ''.join(s[:count])
        else:return 0
        if s[0]=="-":
            res = max(int(res),pow(-2,31))
            return res
        elif s[0]=="+":
            return min(int(res), pow(2, 31)-1)
        else:
            return min(int(res), pow(2, 31)-1)

, len(s)):
addr = addr * 10 + (ord(s[segEnd]) - ord(“0”))
if 0 < addr <= 0xFF:
segments[segId] = addr
dfs(segId + 1, segEnd + 1)
else:
break

    dfs(0, 0)
    return ans

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/restore-ip-addresses/solution/fu-yuan-ipdi-zhi-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


#### [46. 全排列](https://leetcode-cn.com/problems/permutations/)

```python
class Solution:
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        def backtrack(first = 0):
            # 所有数都填完了
            if first == n:  
                res.append(nums[:])
            for i in range(first, n):
                # 动态维护数组
                nums[first], nums[i] = nums[i], nums[first]
                # 继续递归填下一个数
                backtrack(first + 1)
                # 撤销操作
                nums[first], nums[i] = nums[i], nums[first]
        
        n = len(nums)
        res = []
        backtrack()
        return res


作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/permutations/solution/quan-pai-lie-by-leetcode-solution-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

53. 最大子数组和

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        for i in range(len(nums)):
            if i==0: continue
            nums[i] = max(nums[i], nums[i-1]+nums[i])
        print(nums)
        return max(nums)

8. 字符串转换整数 (atoi)

import re
class Solution:
    def myAtoi(self, str: str) -> int:
        INT_MAX = 2147483647    
        INT_MIN = -2147483648
        str = str.lstrip()      #清除左边多余的空格
        num_re = re.compile(r'^[\+\-]?\d+')   #设置正则规则
        num = num_re.findall(str)   #查找匹配的内容
        num = int(*num) #由于返回的是个列表,解包并且转换成整数
        return max(min(num,INT_MAX),INT_MIN)    #返回值
class Solution:
    def myAtoi(self, s: str) -> int:
        s = s.strip()
        p = False
        if len(s)!=0:s = list(s)
        else: return 0
        if s[0] == "-" or s[0] == "+":
            count = 1
            for i in range(1,len(s)):
                if (s[i]<"0" or s[i]>"9"):break
                count+=1
            if count!=1: res = ''.join(s[:count])
            else:return 0
        elif s[0]>="0" and s[0]<="9":
            count = 0
            for i in range(len(s)):
                if (s[i]<"0" or s[i]>"9"):break
                count+=1
            res = ''.join(s[:count])
        else:return 0
        if s[0]=="-":
            res = max(int(res),pow(-2,31))
            return res
        elif s[0]=="+":
            return min(int(res), pow(2, 31)-1)
        else:
            return min(int(res), pow(2, 31)-1)

你可能感兴趣的:(python)