算法刷题复习计划一

复习打卡全面汇总一


连续复习打卡第一天

<<算法刷题打卡第1天:两数之和>>

遇到的问题:

  1. 暴力解题法: 忽略掉了双层 for 循环里层循环可以从 i+1 开始进行时间复杂度优化。
    class Solution:
        def twoSum(self, nums: List[int], target: int) -> List[int]:
            hash_map = dict()
            for i, x in enumerate(nums):
                for j, y in enumerate(nums):
                    if x + y == target and i != j:
                        return [i, j]
    
  2. HashMap解法: 忽略了 if hash_map.get(target-x) 会将 0 算作不满足条件,需要加 is None
    class Solution:
        def twoSum(self, nums: List[int], target: int) -> List[int]:
            hash_map = dict()
            for i, x in enumerate(nums):
                if hash_map.get(target-x) is not None:
                    return [hash_map.get(target-x), i]
                hash_map[x] = i
    

更新时间:2022-11-30


连续复习打卡第二天

<<算法刷题打卡第2天:三个数的最大乘积>>

遇到的问题:

  1. 排序法:
    class Solution:
        def maximumProduct(self, nums: List[int]) -> int:
            nums.sort()
            return max(nums[0]*nums[1]*nums[-1], nums[-1]*nums[-2]*nums[-3])
    
  2. 线性扫描:
    class Solution:
        def maximumProduct(self, nums: List[int]) -> int:
            max1, max2, max3 = -inf, -inf, -inf
            min1, min2 = inf, inf
            for i in nums:
                if i > max1:
                    max3 = max2
                    max2 = max1
                    max1 = i
                elif i > max2:
                    max3 = max2
                    max2 = i
                elif i > max3:
                    max3 = i
                if i < min1:
                    min2 = min1
                    min1 = i
                elif i < min2:
                    min2 = i
            return max(max1*max2*max3, max1*min1*min2)
    

<<算法刷题打卡第2天:反转链表>>

遇到的问题:

  1. 迭代:

    class Solution:
        def reverseList(self, head: ListNode) -> ListNode:
            prev = None
            while head:
                temp = head.next
                head.next = prev
                prev = head
                head = temp
            return prev 
    
  2. 头递归: 每次迭代后的结果也需要返回,而最后为 None 的返回只是结束条件。需要复习!! (2022-12-02 已重温)

    class Solution:
        def reverse(self, prev, node):
            if node is None:
                return prev
            temp = node.next
            node.next = prev
            return self.reverse(node, temp)
        def reverseList(self, head: ListNode) -> ListNode:
            return self.reverse(None, head)
    
  3. 尾递归: 只记得递归函数是自己的下下个节点指向自己,自己的下个节点指向None,忘记需要使用新的节点来保留递归结果,以及递归需要在反转链表逻辑之前。需要复习!! (2022-12-02 已重温)

    class Solution:
        def reverseList(self, head: ListNode) -> ListNode:
            if head is None or head.next is None:
                return head
            new_head = self.reverseList(head.next)
            head.next.next = head
            head.next = None
            return new_head
    

更新时间:2022-12-01


连续复习打卡第三天

<<算法刷题打卡第3天:求平方根>>

遇到的问题:

  1. 二分查找:

    class Solution:
        def mySqrt(self, x: int) -> int:
            left = 0
            right = x
            while left <= right:
                mid = int((left+right)/2)
                if mid*mid <= x:
                    left = mid + 1
                else:
                    right = mid - 1
            return left - 1 
    
  2. 牛顿递归: 牛顿迭代公式为: x k − 1 = − f ( x k ) f ′ ( x k ) + x k x_{k-1}=-\frac{f(x_k)}{f'(x_k)}+x_k xk1=f(xk)f(xk)+xk,把 r e s 2 − x = 0 res^2 - x = 0 res2x=0 带入推导就行,记得写代码的时候运算顺序要加括号…

    class Solution:
        def mySqrt(self, x: int) -> int:
            res = x
            while abs(res*res - x) > 0.01:
                res = res - (res*res - x)/(2*res)
            return int(res)
    

更新时间:2022-12-02


连续复习打卡第四天

<<算法刷题打卡第4天:寻找数组的中心下标>>

遇到的问题:

  1. 单指针:

    class Solution:
        def pivotIndex(self, nums: List[int]) -> int:
            left, sums = 0, sum(nums)
            for i, x in enumerate(nums):
                if left*2 + x == sums:
                    return i
                left += x
            return -1
    
  2. 双指针:

    class Solution:
        def pivotIndex(self, nums: List[int]) -> int:
            left, right = 0, sum(nums)
            for i, x in enumerate(nums):
                left += x
                if left == right:
                    return i
                right -= x
            return -1
    

更新时间:2022-12-03


连续复习打卡第五天

<<算法刷题打卡第5天:删除有序数组中的重复项>>

遇到的问题:

  1. 快慢指针: 相比之前程序做优化。快指针不需要知道下标位置,直接对数组遍历即可。
    class Solution:
        def removeDuplicates(self, nums: List[int]) -> int:
            left = 0
            for x in nums[1:]:
                if nums[left] != x:
                    left += 1
                    nums[left] = x
            return left + 1
    

更新时间:2022-12-04


连续复习打卡第六天(补)

<<算法刷题打卡第6天:计数质数>>

遇到的问题:

  1. 暴力算法:

    class Solution:
        def countPrimes(self, n: int) -> int:
            def Primes(x):
                if x < 2:
                    return False
                for i in range(2, x):
                    if i * i > x:
                        break
                    if x % i == 0:
                        return False
                return True
            res = 0
            for i in range(n):
                if Primes(i) is True:
                    res += 1
            return res
    
  2. 埃氏筛:可以定一个变量来统计质数的数量,避免最后的求和,以及 n 小于 2 的判定,但是理论上没什么区别。

    class Solution:
        def countPrimes(self, n: int) -> int:
            if n < 2:
                return 0
            res = [1]*n
            for i in range(2, n):
                if res[i]:
                    num = i*i
                    while num < n:
                        res[num] = 0
                        num += i
            return sum(res) - 2
    

更新时间:2022-12-07


连续复习打卡第七天(补)

<<算法刷题打卡第7天:两数之和 II - 输入有序数组>>

遇到的问题:

  1. 二分查找:无

    class Solution:
        def twoSum(self, numbers: List[int], target: int) -> List[int]:
            for i in range(len(numbers)):
                l, r = i + 1, len(numbers) - 1
                target_num = target - numbers[i]
                while l <= r:
                    mid = int((l+r)/2)
                    if numbers[mid] < target_num:
                        l = mid + 1
                    elif numbers[mid] > target_num:
                        r = mid - 1
                    else:
                        return i+1, mid+1
    
  2. 前后指针:无

    class Solution:
        def twoSum(self, numbers: List[int], target: int) -> List[int]:
            l, r = 0, len(numbers) - 1
            while l < r:
                if numbers[l] + numbers[r] > target:
                    r -= 1
                elif numbers[l] + numbers[r] < target:
                    l += 1
                else:
                    return l + 1, r + 1
    

更新时间:2022-12-07


连续复习打卡第八天

<<算法刷题打卡第8天:斐波那契数列>>

遇到的问题:

  1. 暴力递归:很难想到,一般人可能不这么写这道题目…

    class Solution:
        def fib(self, n: int) -> int:
            if n < 2:
                return n
            return (self.fib(n-1) + self.fib(n-2)) % 1000000007
    
  2. 去重递归:去重后速度还行,相当于时间复杂度优化为 O ( n ) O(n) O(n) 了,但是空间复杂度也是 O ( n ) O(n) O(n),感觉正常人不会这么写,明显双指针更好想到。

    class Solution:
        save_res = {0:0, 1:1}
        def fib(self, n: int) -> int:
            if self.save_res.get(n) is not None:
                return self.save_res[n]
            self.save_res[n] = (self.fib(n-1) + self.fib(n-2)) % 1000000007
            return self.save_res[n]
    
  3. 双指针迭代:最优解以及最容易想到的操作。

    class Solution:
        def fib(self, n: int) -> int:
            if n < 2:
                return n
    
            p1, p2 = 0, 1
            for _ in range(n-1):
                p3 = p2
                p2 = p1 + p3
                p1 = p3
            return p2 % 1000000007
    

更新时间:2022-12-07


连续复习打卡第九天

<<算法刷题打卡第9天:排列硬币>>

遇到的问题:

  1. 暴力迭代: 相比之前程序做优化。快指针不需要知道下标位置,直接对数组遍历即可。

    class Solution:
        def removeDuplicates(self, nums: List[int]) -> int:
            left = 0
            for x in nums[1:]:
                if nums[left] != x:
                    left += 1
                    nums[left] = x
            return left + 1
    
  2. 二分查找: 需要查找到最后,最后返回左指针的前一个,因为不论是等于还是小于最终都会变成 左指针 = 能够满足的行数 + 1

    class Solution:
        def arrangeCoins(self, n: int) -> int:
            l, r = 0, n
            while l <= r:
                mid = int((l+r)/2)
                if (mid+mid*mid)/2 > n:
                    r = mid - 1
                else:
                    l = mid + 1
            return l - 1
    
  3. 牛顿迭代: 记着牛顿迭代公式: x k − 1 = − f ( x k ) f ′ ( x k ) + x k x_{k-1}=-\frac{f(x_k)}{f'(x_k)}+x_k xk1=f(xk)f(xk)+xk

    	class Solution:
    	    def arrangeCoins(self, n: int) -> int:
    	        x = n
    	        while abs(x+x*x - 2*n) > 1e-5:
    	            x = (x*x+2*n)/(1+2*x)
    	        return int(x)
    
  4. 数学推导: 解方程,等差数列求和,牛顿迭代也需要, S n = n ( a 1 + a n ) 2 Sn=\frac{n(a1+an)}{2} Sn=2n(a1+an)

    class Solution:
        def arrangeCoins(self, n: int) -> int:
            return int(pow((2*n+1/4),0.5)-1/2)
    

更新时间:2022-12-08


连续复习打卡第十天

<<算法刷题打卡第10天:环形链表>>

遇到的问题:

  1. 哈希表: 利用对走过的指针进行存储,每次都判断在不在哈希表里,如果在就是环形,不在就添加进去,直到为空。

            node_dict = dict()
            while head:
                if not node_dict.get(head):
                    node_dict[head] = True
                    head = head.next
                else:
                    return True
            return False
    
  2. 快慢指针: 主要思路就是慢指针一次走一步,快指针一次走两步,利用步长不相同的特点,如果是环形快指针早晚会追上慢指针的思路进行判断。

    class Solution:
        def hasCycle(self, head: Optional[ListNode]) -> bool:
            if head is None:
                return False
            s, q = head, head.next
            while q:
                if s == q:
                    return True
                if q is None or q.next is None:
                    return False
                s = s.next
                q = q.next.next
    
  3. 单指针: 应该叫过河拆桥解法,指针遍历到自己下一个的时候,使用中间变量把之前过来的路断掉,用破坏链表结构的方式来判断是否为环形链表。

    class Solution:
        def hasCycle(self, head: Optional[ListNode]) -> bool:
            if head is None:
                return False
            while head:
                if head == 1:
                    return True
                if head is None or head.next is None:
                    return False
                tmp = head.next
                head.next = 1
                head = tmp
    

更新时间:2022-12-09


连续复习打卡第十一天

<<算法刷题打卡第11天:合并两个有序数组>>

遇到的问题:

  1. 直接合并后排序: python可以直接用 nums1[m:] = nums2 替换某几个值。

    class Solution:
        def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
            """
            Do not return anything, modify nums1 in-place instead.
            """
            for i, x in enumerate(nums2):
                nums1[m+i] = x
            nums1.sort()
    
  2. 双指针: 需要开辟额外的存储空间,因为知道了逆向双指针,这个就不太容易想到了,毕竟不是最优解法。

    class Solution:
        def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
            """
            Do not return anything, modify nums1 in-place instead.
            """
            res = nums1[:m]
            p1, p2 = 0, 0
            while p1 != m and p2 != n:
                if res[p1] > nums2[p2]:
                    nums1[p1+p2] = nums2[p2]
                    p2 += 1
                else:
                    nums1[p1+p2] = res[p1]
                    p1 += 1
            if p1 != m:
                nums1[p1+p2:] = res[p1:]
            else:
                nums1[p1+p2:] = nums2[p2:]
    
  3. 逆向双指针: 最后 列表2 中可能 有值也可能没值,但是不论有没有都可以直接把剩余的赋值到 列表1 中,不用写判断条件。

    class Solution:
        def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
            """
            Do not return anything, modify nums1 in-place instead.
            """
            length = n + m
            while m != 0 and n != 0:
                if nums1[m-1] > nums2[n-1]:
                    nums1[length-1] = nums1[m-1]
                    m -= 1
                else:
                    nums1[length-1] = nums2[n-1]
                    n -= 1
                length -= 1
            nums1[:n] = nums2[:n]
    

更新时间:2022-12-10


连续复习打卡第十二天

<<算法刷题打卡第12天:子数组最大平均数>>

遇到的问题:

  1. 暴力算法:
    class Solution:
        def findMaxAverage(self, nums: List[int], k: int) -> float:
            res = -inf
            for i in range(len(nums)-k+1):
                if sum(nums[i:i+k])/k > res:
                    res = sum(nums[i:i+k])/k
            return res      
    
  2. 滑动窗口:
    class Solution:
        def findMaxAverage(self, nums: List[int], k: int) -> float:
            roll_mean = sum(nums[:k])/k
            res = roll_mean
            for i in range(len(nums)-k):
                roll_mean += (nums[i+k] - nums[i])/k
                res = max(res, roll_mean)
            return res
    

更新时间:2022-12-11


连续复习打卡第十三天

<<算法刷题打卡第13天:二叉树的最小深度>>

遇到的问题:

  1. 深度优先搜索: 主要是思路,实现方法有很多,记得考虑为空的情况。
    class Solution:
        def minDepth(self, root: Optional[TreeNode]) -> int:
            if root:
                if root.left is None and root.right is None:
                    return 1
                l_depth, r_depth = inf, inf
                if root.left:
                    l_depth = self.minDepth(root.left)
                if root.right:
                    r_depth = self.minDepth(root.right)
                return min(l_depth, r_depth) + 1
            return 0
    
  2. 广度优先搜索: 主要是思路,实现方法有很多,记得考虑为空的情况,广度优先迭代要好写一点,递归的话需要开辟多余的空间用来存储递归结果,这道题不划算,因为这道题只要达到第一个叶子节点就可以返回深度了。
    import collections 
    class Solution:
        def minDepth(self, root: Optional[TreeNode]) -> int:
            quene = collections.deque([[root, 1]])
            while quene:
                node = quene.popleft()
                if node[0]:
                    if node[0].left is None and node[0].right is None:
                        return node[1]
                    quene.append([node[0].left, node[1] + 1])
                    quene.append([node[0].right, node[1] + 1])
            return 0
    

更新时间:2022-12-12


连续复习打卡第十四天

<<算法刷题打卡第14天:最长连续递增序列>>

遇到的问题:

  1. 贪心算法: 可以采用三目运算简化代码。
    class Solution:
        def findLengthOfLCIS(self, nums: List[int]) -> int:
            res, now_length = 1, 1
            for i, j in zip(nums[:-1], nums[1:]):
                now_length = now_length + 1 if i < j else 1
                res = max(res, now_length)
            return res
    

更新时间:2022-12-13


连续复习打卡第十五天

<<算法刷题打卡第15天:柠檬水找零>>

遇到的问题:

  1. 贪心算法:
    class Solution:
        def lemonadeChange(self, bills: List[int]) -> bool:
            dollar_5, dollar_10 = 0, 0
            for i in bills:
                if i == 5:
                    dollar_5 += 1
                elif i == 10:
                    if dollar_5 > 0:
                        dollar_5 -= 1
                        dollar_10 += 1
                    else:
                        return False
                else:
                    if dollar_5 > 0 and dollar_10 > 0:
                        dollar_5 -= 1
                        dollar_10 -= 1
                    elif dollar_5 > 2:
                        dollar_5 -= 3
                    else:
                        return False
            return True
    

更新时间:2022-12-14


连续复习打卡第十六天

<<算法刷题打卡第16天:三角形的最大周长>>

遇到的问题:

  1. 贪心 + 排序:
    class Solution:
        def largestPerimeter(self, nums: List[int]) -> int:
            nums.sort()
            for i in range(len(nums)-3, -1, -1):
                if nums[i] + nums[i+1] > nums[i+2]:
                    return sum(nums[i:i+3])
            return 0
    

更新时间:2022-12-15


连续复习打卡第十七天

<<算法刷题打卡第17天:全局倒置与局部倒置>>

遇到的问题:

  1. 维护后缀最小值: 忘记了,这种算法是为了维持除了当前数值的下一个不可能还有数比现在的数要小,改进了一下写法,感觉这种更好写一点,倒序去做是为了能够一直维护最小值的变量。需要复习!! (2022-12-20 已重温)

    class Solution:
        def isIdealPermutation(self, nums: List[int]) -> bool:
            min_num = inf
            for i in range(len(nums)-1, 1, -1):
                min_num = min(min_num, nums[i])
                if min_num < nums[i-2]:
                    return False
            return True
    

    相同含义的写法,只不过是暴力的,不能优化重复计算最小值,导致超时,这里要注意,上面的做法之所以是倒序是因为正序遍历去判断是没办法获取到最小值的,因为有没遍历到的值,但是倒叙就可以:

    class Solution:
        def isIdealPermutation(self, nums: List[int]) -> bool:
            for i in range(len(nums)-2):
                if nums[i] > min(nums[i+2:]):
                    return False
            return True
    
  2. 归纳证明: 想到了当时力扣官方题解的原理,当前下标不能和当前数值相差超过1…

    class Solution:
        def isIdealPermutation(self, nums: List[int]) -> bool:
            for i, x in enumerate(nums):
                if abs(i-x) > 1:
                    return False
            return True
    

更新时间:2022-12-16


连续复习打卡第十八天

<<算法刷题打卡第18天:二叉树的前序遍历—递归>>

遇到的问题:

  1. 递归算法:
    class Solution:
        def recurse(self, root, res):
            if root is None:
                return res
            res.append(root.val)
            self.recurse(root.left, res)
            self.recurse(root.right, res)
            return res
        def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            return self.recurse(root, [])
    

更新时间:2022-12-17


连续复习打卡第十九天

<<算法刷题打卡第19天:二叉树的中序遍历—递归>>

遇到的问题:

  1. 递归算法:
    class Solution:
        def recurse(self, root, res):
            if root is None:
                return res
            self.recurse(root.left, res)
            res.append(root.val)
            self.recurse(root.right, res)
            return res
        def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            return self.recurse(root, [])
    

<<算法刷题打卡第19天:二叉树的后序遍历—递归>>

遇到的问题:

  1. 递归算法:
    class Solution:
        def recurse(self, root, res):
            if root is None:
                return res
            self.recurse(root.left, res)
            self.recurse(root.right, res)
            res.append(root.val)
            return res
        def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            return self.recurse(root, [])
    

更新时间:2022-12-18


连续复习打卡第二十天

<<算法刷题打卡第20天:二叉树的层序遍历—递归>>

遇到的问题:

  1. 递归算法:
    class Solution:
        def recurse(self, root, res, deep):
            if root is None:
                return res
            if len(res) == deep:
                res.append([])
            res[deep].append(root.val)
            self.recurse(root.left, res, deep+1)
            self.recurse(root.right, res, deep+1)
            return res
        def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
            return self.recurse(root, [], 0)
    

更新时间:2022-12-19


连续复习打卡第二十一天

<<算法刷题打卡第21天:二叉树的前序遍历—迭代>>

遇到的问题:

  1. 迭代算法: 前序遍历直接把左右节点都入到栈中,就可以不需要当前节点了,没想到这一点。需要复习!! (2022-12-21 2022-12-22 已重温)
    class Solution:
        def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            res = []
            stack = [root]
            while stack:
                node = stack.pop()
                if node is not None:
                    res.append(node.val)
                    stack.append(node.right)
                    stack.append(node.left)
            return res
    

<<算法刷题打卡第21天:二叉树的中序遍历—迭代>>

遇到的问题:

  1. 迭代算法: 中序遍历需要先入栈,之后出栈的时候打印,但是如何完成这个操作有点难想到…需要复习!! (2022-12-21 2022-12-22 已重温)
    class Solution:
        def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            res, stack = [], []
            node = root
            while stack or node:
                while node:
                    stack.append(node)
                    node = node.left
                node = stack.pop()
                res.append(node.val)
                node = node.right
            return res
    

更新时间:2022-12-20


连续复习打卡第二十二天

<<算法刷题打卡第22天:二叉树的后序遍历—迭代>>

遇到的问题:

  1. 迭代算法: 忘完了…再次入栈,记忆节点都忘记了… 需要复习!! (2022-12-22 已重温)
    class Solution:
        def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            prev = None
            res, stack = [], []
            while root or stack:
                while root:
                    stack.append(root)
                    root = root.left
                root = stack.pop()
                if root.right is None or root.right == prev:
                    res.append(root.val)
                    prev = root
                    root = None
                else:
                    stack.append(root)
                    root = root.right
            return res
    

更新时间:2022-12-21


连续复习打卡第二十三天

<<算法刷题打卡第23天:二叉树的层序遍历—迭代>>

遇到的问题:

  1. 迭代算法:
    class Solution:
        def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
            stack = [[root, 0]]
            res = []
            while stack:
                node, deep = stack.pop()
                if node:
                    if len(res) < deep+1:
                        res.append([])
                    res[deep].append(node.val)
                    stack.append([node.right, deep+1])
                    stack.append([node.left, deep+1])
            return res
    

更新时间:2022-12-22


连续复习打卡第二十四天

<<算法刷题打卡第24天:盒子中小球的最大数量>>

遇到的问题:

  1. 哈希表:
    class Solution:
        def countBalls(self, lowLimit: int, highLimit: int) -> int:
            res, box_counts = 0, {}
            for i in range(lowLimit, highLimit + 1):
                box, value = 0, i
                while value != 0:
                    box += value % 10
                    value //= 10
                if box_counts.get(box):
                    box_counts[box] += 1
                else:
                    box_counts[box] = 1
                res = max(box_counts[box], res)
            return res
    

更新时间:2023-01-03


连续复习打卡第二十五天

<<算法刷题打卡第25天:二叉树的前序遍历—Morris 遍历>>

遇到的问题:

  1. Morris 遍历: 完啦,芭比Q了,忘完了个p的了… 需要复习!!
    class Solution:
        def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            res = []
            while root:
                mostright = root.left
                if mostright:
                    while mostright.right and mostright.right != root:
                        mostright = mostright.right
                    if mostright.right is None:
                        mostright.right = root
                        res.append(root.val)
                        root = root.left
                        continue
                    else:
                        mostright.right = None
                else:
                    res.append(root.val)
                root = root.right
            return res
    

<<算法刷题打卡第25天:二叉树的中序遍历—Morris 遍历>>

遇到的问题:

  1. Morris 遍历: 完啦,芭比Q了,也忘完了个p的了… 需要复习!!
    class Solution:
        def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            res = []
            while root:
                mostright = root.left
                if mostright:
                    while mostright.right and mostright.right != root:
                        mostright = mostright.right
                    if mostright.right is None:
                        mostright.right = root
                        root = root.left
                        continue
                    else:
                        mostright.right = None
                res.append(root.val)
                root = root.right
            return res
    

更新时间:2023-01-04


连续复习打卡第二十六天

<<算法刷题打卡第26天:二叉树的后序遍历—Morris 遍历>>

遇到的问题:

  1. Morris 遍历: 完啦,芭比Q了,都忘完了个p的了… 需要复习!!
    class Solution:
        def reversal(self, node):
            prev = None
            while node:
                temp = node.right
                node.right = prev
                prev = node
                node = temp
            return prev
    
        def nodeprint(self, node, res):
            node = self.reversal(node)
            mid = node
            while mid:
                res.append(mid.val)
                mid = mid.right
            self.reversal(node)
    
        def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
            node, res = root, []
            while root:
                rightnode = root.left
                if rightnode:
                    while rightnode.right and rightnode.right != root:
                        rightnode = rightnode.right
                    if rightnode.right is None:
                        rightnode.right = root
                        root = root.left
                        continue
                    else:
                        rightnode.right = None
                        self.nodeprint(root.left, res)
                root = root.right
            self.nodeprint(node, res)
            return res
    

更新时间:2023-01-05


连续复习打卡第二十七天

<<算法刷题打卡第27天:省份数量—深度优先搜索>>

遇到的问题:

  1. 深度优先搜索: 写法不同,但是差不多,都是深度优先搜索。
    class Solution:
        def dfs(self, i, length, isConnected, visit_map):
            for j in range(length):
                if isConnected[i][j] == 1 and visit_map[j]:
                    visit_map[j] = False
                    self.dfs(j, length, isConnected, visit_map)
    
        def findCircleNum(self, isConnected: List[List[int]]) -> int:
            length, res = len(isConnected), 0
            visit_map = [True] * length
            for i in range(length):
                if visit_map[i]:
                    self.dfs(i, length, isConnected, visit_map)
                    res += 1
            return res
    

更新时间:2023-01-06


连续复习打卡第二十八天

<<算法刷题打卡第28天:省份数量—广度优先搜索>>

遇到的问题:

  1. 广度优先搜索:
    class Solution:
        def findCircleNum(self, isConnected: List[List[int]]) -> int:
            length, res = len(isConnected), 0
            visit_map = [True] * length
            for i in range(length):
                if visit_map[i]:
                    citys = [i]
                    while citys:
                        now_city = citys.pop()
                        visit_map[now_city] = False
                        for j in range(length):
                            if visit_map[j] and isConnected[now_city][j]:
                                citys.append(j)
                    res += 1
            return res
    

更新时间:2023-01-07


连续复习打卡第二十九天

<<算法刷题打卡第29天:省份数量—并查集>>

遇到的问题:

  1. 并查集: 本次复习没有使用对deep的判断进行处理加快算法速度,实现的时候,对于更改根节点的时候需要注意,是更改根节点,而不是更改当前节点的上一个节点,还有就是遍历map的时候,内层循环可以从 i+1 开始节省一半的空间复杂度。 可以稍微复习
    class Solution:
        def findCircleNum(self, isConnected: List[List[int]]) -> int:
            def find(i):
                if root[i] != i:
                    root[i] = find(root[i])
                return root[i]
    
            def merge(i, j):
                roota, rootb = find(i), find(j)
                if roota != rootb:
                	# 根节点改变,需要注意是 root[roota] = rootb,而不是 root[i] = rootb
                    root[roota] = rootb
    
            length = len(isConnected)
            root = list(range(length))
            
            for i in range(length):
                for j in range(i+1, length):
                    if isConnected[i][j] == 1:
                        merge(i, j)
    
            return sum(i == root[i] for i in range(length))
    

更新时间:2023-01-08


连续复习打卡第三十天

<<算法刷题打卡第30天:生成交替二进制字符串的最少操作数>>

遇到的问题:

  1. 模拟(写法一):无
    class Solution:
        def minOperations(self, s: str) -> int:
            q1, q2 = 0, 0
            for i in range(len(s)):
                if i % 2 != 1:
                    if s[i] == "0":
                        q1 += 1
                    else:
                        q2 += 1
                else:
                    if s[i] == "0":
                        q2 += 1
                    else:
                        q1 +=1
            return min(q1, q2)
    
  2. 模拟(写法二):我写的是两种情况都模拟,官方的是模拟其中一种,官方的代码简短一点,但是运行貌似我的快一点。
    class Solution:
        def minOperations(self, s: str) -> int:
            res = sum(i % 2 == int(x) for i, x in enumerate(s))
            return min(res, len(s) - res)
    

更新时间:2023-01-09

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏秃然

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值