力扣刷题_主题库(按题目顺序)_python

说明

各位码友好,此文章仅记录自己在力扣上的刷题笔记,写的非常简略,外人看不一定好理解,若有耽搁各位码友的时间,还请见谅。

文章目录

1. 两数之和

(1)知识点
在这里插入图片描述

思路: 通过字典用保存原数组的值和索引。

(3)结果
在这里插入图片描述

2. 两数相加

思路:递归求解

(2)结果
在这里插入图片描述

3. 无重复字符的最长子串

思想——滑动窗口,维护一个窗口,记录窗口最左边的索引、当前最长长度、当前窗口长度。若已存在新准备要进入窗口的字符,则通过while循环从窗口左边一直移除,移除到没有新准备进入窗口的字符时,为止。

(2)结果
在这里插入图片描述

4. 寻找两个正序数组的中位数

思路

   从小到大依次遍历,使用right保留当前数值,left保留前一个数;共遍历 (len1+len2) / 2次;
  如果len是奇数,返回right; 如果是偶数,返回(right+left)/ 2;如果是奇数,返回right。
  这里有个非常重要的边界分析思想:当只有两种情况时,将其中一种情况的边界全部分析完,然后剩下的就是另外一种情况了。

(2)结果
在这里插入图片描述

5. 最长回文子串

思路:分为两种情况,分别为回文个数为奇数或偶数

  我的思路非常简洁:分为两种情况,分别为回文个数为奇数或偶数;
  当个数为奇数时:把每一个字符都当作中间点,向两边延伸,记录最长的回文字符串个数以及中间点的索引;
  当个数为偶数时: 把每一个字符都当作最中间的两个数字的左边那一个,然后向两边延申,记录最长和中间点索引,最后返回最长的那个回文串。

(2)结果
在这里插入图片描述
在这里插入图片描述

6. Z字型变换(赞)

思路:看图,很有意思

  Step1: 如果numRows == 1,则返回原数据
  Step2: //

(2)结果
在这里插入图片描述

8. 字符串转换整数

在这里插入图片描述在这里插入图片描述

9. 回文数

思想: 将数字转换程字符串,然后前后对照即可

(2)结果
在这里插入图片描述

11.盛最多水的容器(赞)

思想:从前后两端进行比较,每次移动,其底都会减1,此时,如移动长板子,则面积一定会减小(因为高是由短板子决定的,此时底又减少了1,所以面积一定减少);若移动短板子,面积可能增大、减少、不变。

  所以如果想求最大面积,每次移动短板子即可
(2)代码

在这里插入图片描述

12. 整数转罗马数字

(1)思想
此题最重要的思想就是将所有的 整数和罗马数字全部罗列出来,然后再进行穷举即可。
(2)代码
在这里插入图片描述

13. 罗马数字转整数

思想:主要在于理解罗马数字的构成:罗马数字序列中,如果:左边的数字 < 右边的数字,那么前面累加的和应该减去左边的数字;反之,则加

tips:
注意图中:
索引-1: 表示取最后一个元素

(2)代码
在这里插入图片描述

15 三数之和_中等

思想: 排序、双指针找数、去重

Step1: 排序
Step2:双指针找数
Step3:去重
(2)代码:
在这里插入图片描述

16 最接近的三数之和_中等

思想: 排序、两边往中间跑

Step1: 先排序
Step2:从中间向两边跑
(2)代码
在这里插入图片描述

17. 电话号码的字母组合

思想:递归获取每一个数字对应的字母

(2)代码
在这里插入图片描述

18. 四数之和

同三数之和差不多,代码如下:

在这里插入图片描述

19. 删除链表的倒数第 N 个结点(赞)

思路: 前后(pre、end)双指针,先使其间隔n个节点、再同步前进是end指针指向最后一个节点。此时,pre.next即为因删除的节点。正常删除即可

代码即结果:
在这里插入图片描述

20. 有效的括号(赞)

思想:字典+栈(好好看看python中字典和栈的运用)

代码:
在这里插入图片描述

21. 合并两个有序链表

思路:遍历选取链头节点最小值,然后被选节点前移

在这里插入图片描述

22. 括号生成(赞)

思路:深度优先搜索,先添加左括号,后添加右括号

代码
在这里插入图片描述

23. 合并K个升序链表

思想:和21题一样,遍历选取链头节点最小值,然后被选节点前移

代码:
在这里插入图片描述

24. 两两交换链表中的节点

思想:画图找到规律,然后while循环

在这里插入图片描述
代码:
在这里插入图片描述

25.K个一组翻转链表

思路:找到k个一组的起始点,翻转链表,然后重置节点,进行循环

在这里插入图片描述
代码:
在这里插入图片描述

class Solution:
    def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        if head == None or k == 1:
            return head
        
        count = 1
        node1 = head
        node2 = head
        #  1.找到新链头节点
        while node2 != None and count < k:
            node2 = node2.next
            count += 1
        if node2 == None:
            return head
        newHead = node2

        count = 1
        while node2!= node1:
            # 2.标记后两个起始点
            node3 = node2.next
            node4  = node3
            while node4!= None and count < k:
                node4 = node4.next
                count += 1
            if node4 == None:
                node4 = node3
            # 3.反转链表
            if k == 2:
                node2.next = node1
            else:
                cur = node1
                mid = cur.next
                end = mid.next
                while end != node2:
                    mid.next = cur
                    cur = mid
                    mid = end
                    end = end.next
                end.next = mid
                mid.next = cur

            # 4. 重置节点,方便循环
            node1.next = node4
            node1 = node3
            node2 = node4
            count = 1
        
        return newHead

26. 删除有序数组中的重复项

思路:前后p、q双指针,若有不同,p前移

代码:
在这里插入图片描述

28. 实现strStr()

思想1: KMP(字符串匹配算法)

思想2: 使用库函数 return haystack.index(needle) if needle in haystack else -1

代码:
在这里插入图片描述

29. 两数相除( 非常重要!!!!,一定要看题解 )

思想: 除法越界、位运算

题解(一定要看题解): 题解
在这里插入图片描述

30.串联所有单词的子串——(很重要!!!!)

思路:窗口滑动+哈希

代码:
在这里插入图片描述

31.下一个排列

思想:从后数,找到一个比后面一个数小的位置i,然后从最后数找到比nums[i]大一点的值,然后较换,最后将位置i之后的值进行逆置。

代码:
在这里插入图片描述

32. 最长有效括号(很有想法!!!)

思想: 通过栈保存未被匹配的索引,最后计算栈中索引的最大间隔

在这里插入图片描述

34. 在排序数组中查找元素的第一个和最后一个位置

思想:两次二分查找,一次寻找第一次target出现的索引,第2次寻找最后一个target出现的索引

在这里插入图片描述

36. 有效的数独

思想:分别新建行列以及block标记,然后在遍历原数组

代码如下:
在这里插入图片描述

38.外观数列

思想:遍历生成

在这里插入图片描述

39. 组合总和

思想:剪枝 + 回溯(!!!!)

在这里插入图片描述

40. 组合综合Ⅱ(!!!)

思想: 回溯+剪枝

参考别人写的:
在这里插入图片描述
自己写的(超时):
在这里插入图片描述
具体分析:
在这里插入图片描述

41. 缺失的第一个正数

原地哈希(!!!)

在这里插入图片描述

42. 接雨水

思想:左右双指针,记录左右最大值

在这里插入图片描述

43. 字符串相乘

思想: 通过字典将字符串转为数字

在这里插入图片描述

46. 全排列

思想: 位标记+回溯算法

在这里插入图片描述

47.全排类Ⅱ

思想:位运算标记+回溯+列表去重

在这里插入图片描述

48. 旋转图像

在这里插入图片描述

53. 最大子数组和(很重要!!!)

思想: 动态规划,定义dp_i为以nums[i]结尾的最大连续子数组之和,然后进行状态转移

在这里插入图片描述

54. 螺旋矩阵(思想非常奇妙!)

思想: 定义上下左右边界,遍历后就重置边界!

在这里插入图片描述

class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        if matrix == None:
            return None
        
        # 1. 定义上下左右边界
        up = 0
        down = len(matrix) - 1
        left = 0 
        right = len(matrix[0]) - 1 
        res = []

        while True:
            # 2. 右行
            for i in range(left, right+1):
                res.append(matrix[up][i])

            up += 1
            if up > down:
                break

            # 3. 下行
            for i in range(up, down+1):
                res.append(matrix[i][right])

            right -= 1
            if right < left:
                break

            # 4. 左行
            for i in range(right, left-1, -1):
                res.append(matrix[down][i])

            down -= 1
            if down < up:
                break

            # 5. 上行
            for i in range(down,up-1, -1):
                res.append(matrix[i][left])
            
            left += 1
            if left > right:
                break

        return res

55. 跳跃游戏

思想: 标记起跳点能达到的最远距离,遍历;
在这里插入图片描述

59. 螺旋矩阵

思想:定义上下左右边界,然后循环遍历

在这里插入图片描述

class Solution:
    def generateMatrix(self, n: int) -> List[List[int]]:
        if n < 1: 
            return None
        
        # 1. 生成二维list
        res = [[0 for _ in range(n)] for _ in range(n)] 
        
        # 2. 定义初始位置上下左右边界 和 数值
        l, r, t, b = 0, n-1, 0, n-1
        num, target = 1, n**2

        # 3. 按照螺旋顺序进行填充数据
        while num <= target:
            # 右行
            for i in range(l, r+1):
                res[t][i] = num
                num += 1
            t += 1
            
            # 下行
            for j in range(t, b+1):
                res[j][r] = num
                num += 1
            r -= 1

            # 左行
            for k in range(r, l-1, -1):
                res[b][k] =num
                num += 1
            b -= 1

            # 上行
            for z in range(b, t-1, -1):
                res[z][l] = num
                num += 1
            l += 1
        return res

61. 旋转链表

思想:前后双指针,且间隔k个间距

在这里插入图片描述

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
        # 1.判空
        if head == None:
            return None

        # 2. 计算链表长度
        pre = head 
        num = 1
        while pre.next != None:
            num += 1
            pre = pre.next

        k = k % num
        if k == 0:
            return head

        pre = head
        end = head

        # 3.按end与pred间距k各单位
        for i in range(k):
            if end.next != None:
                end = end.next

        # 4. 间隔k使end至末尾点
        while end.next != None:
            end = end.next
            pre = pre.next

        # 5. 使末尾执行头节点
        end.next = head

        # 6. 令pred.next 为头节点,并返回
        head = pre.next
        pre.next = None
        return head

62. 不同路径

思想:每一格的路径数 = 上面和左边的路径之和

在这里插入图片描述

73. 矩阵置零

思想1:先扫描一边,使用两个listt分别记录哪些行,哪些列有0;然后再遍历去置零

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        # 1. 判断空处理
        if matrix == None:
            return None
        
        # 2.记录出现0的行列号
        row = []
        cul = []

        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j] == 0:
                    if i not in row:
                        row.append(i)
                    if j not in cul:
                        cul.append(j)

        # 3. 清零
        # 3.1 行清0
        for i in row:
            for j in range(len(matrix[0])):
                matrix[i][j] = 0
        
        for j in cul:
            for i in range(len(matrix)):
                matrix[i][j] = 0

思想2***: 先使用两个标志位,记录第一行和第一列是否有0, 然后从第2行、第2列扫描,如果有0,则使用第一行和第一列对应位置记录;最后,根据扫描第一行和第一列的位置,置零。

借鉴的讨论区大佬的代码:

class Solution:
    def setZeroes(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        row = len(matrix)
        col = len(matrix[0])
        row0_flag = False
        col0_flag = False
        # 找第一行是否有0
        for j in range(col):
            if matrix[0][j] == 0:
                row0_flag = True
                break
        # 第一列是否有0
        for i in range(row):
            if matrix[i][0] == 0:
                col0_flag = True
                break

        # 把第一行或者第一列作为 标志位
        for i in range(1, row):
            for j in range(1, col):
                if matrix[i][j] == 0:
                    matrix[i][0] = matrix[0][j] = 0
        #print(matrix)
        # 置0
        for i in range(1, row):
            for j in range(1, col):
                if matrix[i][0] == 0 or matrix[0][j] == 0:
                    matrix[i][j] = 0

        if row0_flag:
            for j in range(col):
                matrix[0][j] = 0
        if col0_flag:
            for i in range(row):
                matrix[i][0] = 0

作者:powcai
链接:https://leetcode.cn/problems/set-matrix-zeroes/solutions/6594/o1kong-jian-by-powcai/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

102. 二叉树的层序遍历

思想:使用队列实现,在python中队列: queue = collections.deque([root]),即可完成初始化

在这里插入图片描述

77.组合(从[1, n]中选出所有k个数的组合)**

思路:排列组合的一个公式,C(n, k) = C(n - 1, k) + C(n - 1, k - 1)。从n个数中选k个数的所有情况可以分为“没选第n个数”和“选了第n个数”两类。如果没选第n个数,那么k个数全部从其余的n - 1个数中选出,共有C(n - 1, k)种方式;如果选了第n个数,那还需要从剩余的n - 1个数中选k - 1个数,共有C(n - 1, k - 1)种方式:

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        if k == 1:
            return [[i] for i in range(1, n+1)]
        if k == n:
            return [list(range(1, n+1))]

        return self.combine(n=n-1, k=k) + [ [n] + x for x in self.combine(n=n-1, k=k-1) ]

82. 删除有序链表中的重复元素

在这里插入图片描述

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

class Solution:
    def deleteDuplicates(self, head: Optional[ListNode]) -> Optional[ListNode]:
        if not head or not head.next:
            return head
        
        # (重要)设置一个哑节点,防止头节点被删除,最后返回dummy即可
        dummy = ListNode(0)
        dummy.next = head
        pre, cur = dummy, head

        while cur:
            # Step1: 重复节点的最后位置
            while cur.next and cur.val == cur.next.val:
                cur = cur.next
            
            # 移动pre指针
            if pre.next == cur:
                pre = pre.next
            else:
                pre.next = cur.next
            cur = cur.next
        
        return dummy.next
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值