代码随想录刷题笔记 (python版本) 持续更新.....

news2024/11/24 22:53:59

代码随想录刷题笔记总结:
https://www.programmercarl.com/

个人学习笔记 如有错误欢迎指正交流

1. 数组

1.1 理论基础

详细介绍:https://www.programmercarl.com/%E6%95%B0%E7%BB%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

  • 数组下标都是从0开始的。
  • 数组内存空间的地址是连续的

1.2 二分查找

1.2.1 二分查找 (**)

1. 题目链接: https://leetcode.cn/problems/binary-search/description/
在这里插入图片描述

2. 思路:

  • 方法1: 初始化 right = len(nums)-1, [left, right] left <= right 左闭右闭
    那么right = mid-1, 因为 [mid, right] 已经考虑了 所以剩余[left, mid-1] mid

  • 方法2: 初始化right = len(nums), [left, right) left < right 左闭右开 那么right = mid,
    因为 [mid, right) 已经考虑了 所以剩余[left, mid) 这里就考虑mid了

3. AC代码:

"""
题目: 704. 二分查找
链接: https://leetcode.cn/problems/binary-search/description/
思路:
mid = left + right
方法1: 初始化 right = len(nums)-1, [left, right] left <= right 左闭右闭 那么right = mid-1, 因为 [mid, right] 已经考虑了 所以剩余[left, mid-1] mid
方法2: 初始化 right = len(nums)-1, [left, right) left < right 左闭右开 那么right = mid, 因为 [mid, right) 已经考虑了 所以剩余[left, mid) 这里就考虑mid了
两个方法的剩余考虑区间保持一致
left统一写法 left = mid +1
关键词: 有序,目标值, 查找,数组元组不重复
"""
class Solution(object):
    def search(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if target < nums[mid]:
                right = mid -1
            elif target > nums[mid]:
                left = left + 1
            else:
                return mid
        return -1
if __name__ == '__main__':
    nums = [-1, 0, 3, 5, 9, 12]
    target = 9
    solution = Solution()
    result = solution.search(nums, target)

    print(f"result: {result}")

1.2.2 搜索插入位置

1. 题目链接: https://leetcode.cn/problems/search-insert-position/description/
在这里插入图片描述

2. 思路:
1. 利用二分查找
他的区别是 没有找到元素的情况返回的是元组插入的索引
关键词: 有序,目标值, 查找,数组元组不重复

3. AC代码:

"""
题目: 35 搜索插入位置
链接: https://leetcode.cn/problems/search-insert-position/description/
思路:
    他的区别是  没有找到元素的情况返回的是元组插入的索引
    关键词: 有序,目标值, 查找,数组元组不重复
"""
class Solution(object):
    def searchInsert(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        left = 0
        right = len(nums) - 1
        while left <= right:        # 如果元素不存在数组种 那么跳出循环的时候left = right+1的, 最终放回left和right+1都可以
            mid = (left + right) // 2
            if target < nums[mid]:
                right = mid - 1
            elif target > nums[mid]:
                left = mid + 1
            else:
                return mid
        return left


if __name__ == '__main__':
    nums = [1, 3, 5, 6]
    target = 2
    solution = Solution()
    result = solution.searchInsert(nums, target)
    print(f"result: {result}")

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

1. 题目链接: https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/
在这里插入图片描述

2. 思路:
方法1: 先找到一个的位置然后向左右扩散
方法2: 分别找到左边界和右边界

3. AC代码:

"""
题目: 34. 在排序数组中查找元素的第一个和最后一个位置
链接: https://leetcode.cn/problems/find-first-and-last-position-of-element-in-sorted-array/
思路:
    方法1: 先找到一个的位置然后向左右扩散
    方法2: 分别找到左边界和右边界
关键词: 有序,目标值, 查找,数组元组不重复
"""
class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        left = 0
        right = len(nums) - 1
        while left <= right:
            mid = (left + right) // 2
            if target < nums[mid]:
                right = mid - 1
            elif target > nums[mid]:
                left = mid + 1
            else:
                temp = nums[mid]
                i = mid
                j = mid
                while 0 <= i:
                    if nums[i] == target:
                        i -= 1
                    else:
                        break
                while j <= len(nums) - 1:
                    if nums[j] == target:
                        j += 1
                    else:
                        break
                return [i+1, j-1]

        return [-1, -1]

if __name__ == '__main__':
    nums = []
    target = 6
    solution = Solution()
    result = solution.searchRange(nums, target)
    print(f"result: {result}")

1.2.4 x 的平方根

1. 题目链接: https://leetcode.cn/problems/sqrtx/description/
在这里插入图片描述

2. 思路:
这道题目和搜索插入位置题很相似 相当于从[1, 2, 3, …, x] 数组中找到根号x的插入位置

3. AC代码:

"""
题目: 69 x 的平方根
链接: https://leetcode.cn/problems/sqrtx/description/
思路:
     这道题目和35题很相似 相当于从[1, 2, 3, ..., x] 数组中找到根号x的插入位置

"""
class Solution(object):
    def mySqrt(self, x):
        """
        :type x: int
        :rtype: int
        """
        left = 1
        right = x
        while left <= right:
            mid = (left + right) // 2
            if mid * mid < x:
                left = mid + 1
            elif mid * mid > x:
                right = mid -1
            else:
                return mid
        return right
if __name__ == '__main__':
    x = 4
    solution = Solution()
    result = solution.mySqrt(9)
    print(f"result: {result}")

1.2.5 有效的完全平方数

1. 题目链接: https://leetcode.cn/problems/valid-perfect-square/description/
在这里插入图片描述

2. 思路:
相当于从[1, 2,…, x] 里面添加一个找是否存在 根号x 存在返回True 不存在则返回False

3. AC代码:

"""
题目: 367. 有效的完全平方数
链接: https://leetcode.cn/problems/valid-perfect-square/description/
思路:
    相当于从[1, 2,..., x] 里面添加一个找是否存在 根号x 存在返回True 不存在则返回False
"""
class Solution(object):
    def isPerfectSquare(self, num):
        """
        :type num: int
        :rtype: bool
        """
        left = 1
        right = num
        while left <= right:
            mid = (left + right) // 2
            if mid * mid < num:
                left = mid + 1
            elif mid * mid > num:
                right = mid - 1
            else:
                return True
        return False

if __name__ == '__main__':
    num = 1
    solution = Solution()
    result = solution.isPerfectSquare(num)
    print(f"result: {result}")

1.3 移除元素

1.3.1 移除元素

1. 题目链接: https://leetcode.cn/problems/remove-element/description/
在这里插入图片描述

2. 思路:
方法1: 通过索引遍历元素,当前元素不等于val是指针才开始移动而且val_num加1, 那么数组的有效长度是len(nums)-val_num, 否则指针是不移动的。
方法2: 利用快慢指针进行计算,不等于的时候进行赋值, 等于的时候不用管

3.1 (方法一)AC代码:

"""
题目: 27. 移除元素
链接: https://leetcode.cn/problems/remove-element/description/
思路:
    方法1: 通过索引遍历元素,当前元素不等于val是指针才开始移动而且val_num加1, 那么数组的有效长度是len(nums)-val_num, 否则指针是不移动的。
    方法2: 利用快慢指针进行计算,不等于的时候进行赋值, 等于的时候不用管
关键点:
"""
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        val_num = 0
        i = 0
        while i < len(nums)-val_num:
            if nums[i] == val:
                val_num += 1
                for j in range(i, len(nums)-val_num):
                    nums[j] = nums[j+1]
            else:
                i += 1
        return len(nums)-val_num


if __name__ == '__main__':
    nums = [3, 2, 2, 3]
    val = 3
    solution = Solution()
    result = solution.removeElement(nums, val)
    print(f"result: {result}")

3.2 (方法2)AC代码:

"""
题目: 27. 移除元素
链接: https://leetcode.cn/problems/remove-element/description/
思路:
    方法1: 通过索引遍历元素,当前元素不等于val是指针才开始移动而且val_num加1, 那么数组的有效长度是len(nums)-val_num, 否则指针是不移动的。
    方法2: 利用快慢指针进行计算,不等于的时候进行赋值, 等于的时候不用管(推荐使用这个方法 很优雅)
    方法3: 双指针
关键点:
"""
class Solution(object):
    def removeElement(self, nums, val):
        """
        :type nums: List[int]
        :type val: int
        :rtype: int
        """
        slow = 0
        for temp in nums:
            if temp != val:
                nums[slow] = temp
                slow += 1
        return slow



if __name__ == '__main__':
    nums = [3, 2, 2, 3]
    val = 3
    solution = Solution()
    result = solution.removeElement(nums, val)
    print(f"result: {result}")

1.3.2 删除排序数组中的重复项

1. 题目链接: https://leetcode.cn/problems/remove-duplicates-from-sorted-array/description/
在这里插入图片描述

2. 思路:
方法1: slow 慢指针, 遇到新的数字进行赋值并且改变slow,
方法2: temp保存第一个出现的元素, 判断后续元素是否相同, 相同则直接跳过, 不同的话则重新对temp进行赋值
3.1 (方法1)AC代码:

"""
题目: 26 删除有序数组中的重复项
链接: https://leetcode.cn/problems/remove-duplicates-from-sorted-array/description/
思路:
    方法1:  slow 慢指针, 遇到新的数字进行赋值并且改变slow,
    方法2: temp保存第一个出现的元素, 判断后续元素是否相同, 相同则直接跳过, 不同的话则重新对temp进行赋值
"""
class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        slow = 0
        temp = nums[0]
        for num in nums:
            if num != temp:
                slow += 1
                nums[slow] = num
                temp = num
        print(f"slow: {slow+1}")
        return slow+1

if __name__ == '__main__':
    nums = [0,0,1,1,1,2,2,3,3,4]
    solution = Solution()
    result = solution.removeDuplicates(nums)
    print(f"result: {result}, {nums[:result]}")

3.2 (方法1)AC代码:

"""
题目: 26 删除有序数组中的重复项
链接: https://leetcode.cn/problems/remove-duplicates-from-sorted-array/description/
思路:
    slow 慢指针, 遇到新的数字进行赋值并且改变slow
"""
class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        slow = 0
        for current in nums:
            if nums[slow] != current:
                slow += 1
                nums[slow] = current
        return slow+1

if __name__ == '__main__':
    nums = [0,0,1,1,1,2,2,3,3,4]
    solution = Solution()
    result = solution.removeDuplicates(nums)
    print(f"result: {result}, {nums[:result]}")

1.3.3 移动零

1. 题目链接: https://leetcode.cn/problems/move-zeroes/description/
在这里插入图片描述

2. 思路:

  • 用快慢指针对不是0的值依次赋值, 然后对slow之后的下标索引赋值为0

3. AC代码:

"""
题目:  283. 移动零
链接:  https://leetcode.cn/problems/move-zeroes/description/
思路:
    方法1: 用快慢指针对不是0的值依次赋值, 然后对slow之后的下标索引赋值为0
    方法2:
关键词: 移除元素
"""
class Solution(object):
    def moveZeroes(self, nums):
        """
        :type nums: List[int]
        :rtype: None Do not return anything, modify nums in-place instead.
        """
        slow = 0
        for num in nums:
            if num != 0:
                nums[slow] = num
                slow += 1
        for i in range(slow, len(nums)):
            nums[i] = 0
        # print(f"nums: {nums}")
        # print(f"slow: {slow}")
        return nums

if __name__ == '__main__':
    nums = [0, 1, 0, 3, 12]
    solution = Solution()
    result = solution.moveZeroes(nums)
    print(f"result: {result}")

1.3.4 比较含退格的字符串

1. 题目链接: https://leetcode.cn/problems/backspace-string-compare/
在这里插入图片描述

2. 思路:

  • 利用栈去解决, 遇到字符# 进行出栈 最终比较两个栈是否相等
    关键词:退格 抵消

3. AC代码:

class Solution(object):
    def backspaceCompare(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        s_stack = self.backspace(s)
        t_stack = self.backspace(t)
        return s_stack == t_stack
    def backspace(self, str):
        stack = []
        for word in str:
            if word != '#':
                stack.append(word)
            else:
                if stack != []:
                    stack.pop()
        return stack


if __name__ == '__main__':
    s = "ab#c"
    t = "ad#c"
    solution = Solution()
    result = solution.backspaceCompare(s, t)
    print(f"result: {result}")

1.3.5 有序数组的平方

1. 题目链接: https://leetcode.cn/problems/squares-of-a-sorted-array/
在这里插入图片描述

2. 思路:

3.1 (方法1)AC代码:

"""
题目: 977. 有序数组的平方
链接: https://leetcode.cn/problems/squares-of-a-sorted-array/
思路:
    方法1:最简单的方法就是用一个存入平方的值 最后排序
    方法2:利用双指针依次从左从右进行遍历
关键词: 排序, 平方
"""
class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        result = []
        for i, num in enumerate(nums):
            result.append(num * num)
        return sorted(result)
if __name__ == '__main__':
    nums = [-4, -1, 0, 3, 10]
    solution = Solution()
    result = solution.sortedSquares(nums)
    print(f"result: {result}")

3.2 (方法2)AC代码:

"""
题目: 977. 有序数组的平方
链接: https://leetcode.cn/problems/squares-of-a-sorted-array/
思路:
    方法1:最简单的方法就是用一个存入平方的值 最后排序
    方法2:利用双指针依次从左从右进行遍历
关键词: 排序, 平方
"""
class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        left = 0
        right = len(nums) - 1
        res = [None] * len(nums)
        index = len(nums) - 1
        while left <= right:
            if nums[left] * nums[left] < nums[right] * nums[right]:
                res[index] = nums[right] * nums[right]
                right -= 1
            else:
                res[index] = nums[left] * nums[left]
                left += 1
            index -= 1
        # print(f"res: {res}")
        return res
if __name__ == '__main__':
    nums = [-4, -1, 0, 3, 10]
    solution = Solution()
    result = solution.sortedSquares(nums)
    print(f"result: {result}")

1.4 有序数组的平方

1. 题目链接: https://leetcode.cn/problems/squares-of-a-sorted-array/
在这里插入图片描述

2. 思路:

3.1 (方法1)AC代码:

"""
题目: 977. 有序数组的平方
链接: https://leetcode.cn/problems/squares-of-a-sorted-array/
思路:
    方法1:最简单的方法就是用一个存入平方的值 最后排序
    方法2:利用双指针依次从左从右进行遍历
关键词: 排序, 平方
"""
class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        result = []
        for i, num in enumerate(nums):
            result.append(num * num)
        return sorted(result)
if __name__ == '__main__':
    nums = [-4, -1, 0, 3, 10]
    solution = Solution()
    result = solution.sortedSquares(nums)
    print(f"result: {result}")

3.2 (方法2)AC代码:

"""
题目: 977. 有序数组的平方
链接: https://leetcode.cn/problems/squares-of-a-sorted-array/
思路:
    方法1:最简单的方法就是用一个存入平方的值 最后排序
    方法2:利用双指针依次从左从右进行遍历
关键词: 排序, 平方
"""
class Solution(object):
    def sortedSquares(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        left = 0
        right = len(nums) - 1
        res = [None] * len(nums)
        index = len(nums) - 1
        while left <= right:
            if nums[left] * nums[left] < nums[right] * nums[right]:
                res[index] = nums[right] * nums[right]
                right -= 1
            else:
                res[index] = nums[left] * nums[left]
                left += 1
            index -= 1
        # print(f"res: {res}")
        return res
if __name__ == '__main__':
    nums = [-4, -1, 0, 3, 10]
    solution = Solution()
    result = solution.sortedSquares(nums)
    print(f"result: {result}")

1.5 长度最小的子数组

1.5.1 长度最小的子数组

1. 题目链接: https://leetcode.cn/problems/minimum-size-subarray-sum/
在这里插入图片描述

2. 思路:

  • 滑动窗口方法,满足条件时左窗口进行滑动

3. AC代码:

"""
题目: 209. 长度最小的子数组
链接: https://leetcode.cn/problems/minimum-size-subarray-sum/
思路:
    滑动窗口方法,满足条件时左窗口进行滑动
"""
class Solution(object):
    def minSubArrayLen(self, target, nums):
        l = 0
        sum = 0
        res_min = 100001
        for r, num in enumerate(nums):
            sum += num
            while sum >= target:
                res_min = min(res_min, r-l+1)
                sum -= nums[l]
                l += 1
        # print(f"res: {res_min}")
        return 0 if res_min == 100001 else res_min
if __name__ == '__main__':
    target = 7
    nums = [2, 3, 1, 2, 4, 3]
    solution = Solution()
    result = solution.minSubArrayLen(target, nums)
    print(f"result: {result}")

1.5.2 水果成篮 (**)

1. 题目链接: https://leetcode.cn/problems/fruit-into-baskets/description/
在这里插入图片描述

2. 思路:

  1. 滑动窗口利用map,循环遍历fruits数组,将fruits[r]的value值加一,
  2. 如果map长度大于2 那么左滑动串口开始移动,直到fruit[l]的value等于0才可以删除key
  3. 对res_max进行赋值。返回结果

3. AC代码:

"""
题目: 904. 水果成篮
链接: https://leetcode.cn/problems/fruit-into-baskets/description/
思路:
    滑动窗口利用map,循环遍历fruits数组,将fruits[r]的value值加一,
    如果map长度大于2 那么左滑动串口开始移动,直到fruit[l]的value等于0才可以删除key
    对res_max进行赋值。返回结果
"""
class Solution:
    def totalFruit(self, fruits):
        l = 0
        res_max = float("-inf")
        fruits_map = {}
        for r in range(len(fruits)):
            fruits_map[fruits[r]] = fruits_map.get(fruits[r], 0) + 1
            while len(fruits_map) > 2:
                fruits_map[fruits[l]] -= 1
                if fruits_map[fruits[l]] == 0:
                    del fruits_map[fruits[l]]
                l += 1
            res_max = max(res_max, r - l + 1)
        return res_max


if __name__ == '__main__':
    fruits = [0,1,2,2]
    solution = Solution()
    result = solution.totalFruit(fruits)
    print(f"result: {result}")

1.5.3 最小覆盖子串 (**)

1. 题目链接: https://leetcode.cn/problems/minimum-window-substring/

在这里插入图片描述

2. 思路:

  1. 利用map+滑动窗口
  2. 首先将字符串t的所有字符组成key value的形式, 以及初始化总的字符个数
  3. 然后遍历字符串s, 判断当前字符s[r] 是否在t_map的key中, 如果在则s[r]对应的value-1, 判断value是否为0, 如果为0, 那么require_char 可以见第减1
  4. 判断require_char==0, 表示当前滑动窗口包含t字符串, res_str进行赋值, 左滑动窗口向后移动进行找到最小的滑动窗口
  5. 返回res_str

3. AC代码:

"""
题目: 76. 最小覆盖子串
链接: https://leetcode.cn/problems/minimum-window-substring/
思路:
    1. 利用map+滑动窗口
    2. 首先将字符串t的所有字符组成key value的形式, 以及初始化总的字符个数
    3. 然后遍历字符串s, 判断当前字符s[r] 是否在t_map的key中, 如果在则s[r]对应的value-1, 判断value是否为0, 如果为0, 那么require_char 可以见第减1
    4. 判断require_char==0, 表示当前滑动窗口包含t字符串, res_str进行赋值, 左滑动窗口向后移动进行找到最小的滑动窗口
    5. 返回res_str

"""
class Solution(object):
    def minWindow(self, s, t):
        res_str = ""
        t_map = {}
        res_min = float("inf")
        for char in t:
            t_map[char] = t_map.get(char, 0) + 1
        require_char = len(t_map)
        l = 0
        r = 0
        while r < len(s):
            # s_map[s[r]] = s_map.get(s[r], 0) + 1
            if s[r] in t_map:
                t_map[s[r]] -= 1
                if t_map[s[r]] == 0:
                    require_char -= 1
            while require_char == 0:  # 满足要求的时候保存字串的大小
                if r - l + 1 < res_min:
                    res_min = min(res_min, r - l + 1)
                    res_str = s[l:r+1]
                    # print(f"res_str: {res_str}")
                if s[l] in t_map:
                    t_map[s[l]] += 1
                    if t_map[s[l]] > 0:
                        require_char += 1
                l +=1
            r += 1

        return res_str

if __name__ == '__main__':
    s = "ADOBECODEBANC"
    t = "ABC"
    solution = Solution()
    result = solution.minWindow(s, t)
    print(f"result: {result}")

1.6 螺旋矩阵 II

1. 题目链接: https://leetcode.cn/problems/spiral-matrix-ii/
在这里插入图片描述

2. 思路:

  1. 初始化top, down, left, right = 0, n-1, 0, n-1,
  2. 然后顺时针螺旋依次进行赋值, top赋值之后+1, down-1, left+1, right+1依次这样缩小范围即可

3. AC代码:

"""
题目: 59. 螺旋矩阵 II
链接: https://leetcode.cn/problems/spiral-matrix-ii/
思路:
    初始化top, down, left, right = 0, n-1, 0, n-1,
    然后顺时针螺旋依次进行赋值, top赋值之后+1, down-1, left+1, right+1依次这样缩小范围即可
"""
class Solution(object):
    def generateMatrix(self, n):
        num = 1
        top, down, left, right = 0, n-1, 0, n-1
        res = [[0] * n for _ in range(n)]
        while num <= n * n:
            for i in range(left, right+1):
                res[top][i] = num
                num += 1
            top += 1
            for i in range(top, down+1):
                res[i][right] = num
                num += 1
            right -= 1
            for i in range(right, left-1, -1):
                res[down][i] = num
                num += 1
            down -= 1
            for i in range(down, top-1, -1):
                res[i][left] = num
                num += 1
            left += 1
        return res


if __name__ == '__main__':
    n = 3
    solution = Solution()
    result = solution.generateMatrix(n)
    print(f"result: {result}")

1.7 数组总结

详细总结: https://www.programmercarl.com/%E6%95%B0%E7%BB%84%E6%80%BB%E7%BB%93%E7%AF%87.html

2. 链表

本章预览:
在这里插入图片描述

2.1 理论基础

什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。
详细介绍: https://www.programmercarl.com/%E9%93%BE%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

2.2 移除链表元素 (**)

  1. 刷题链接:
    https://leetcode.cn/problems/remove-linked-list-elements/description/
    在这里插入图片描述

2. 思路

  1. 首先定义构造列表和遍历列表的方法(不是必要的)
  2. 利用pre节点
  3. if pre.next.val = val 删除当前节点 操作为pre.next = pre.next.next (如果当前节点的值等于val)
  4. 否则指针继续移动

3. AC代码

"""
题目: 203. 移除链表元素
链接: https://leetcode.cn/problems/remove-linked-list-elements/description/
思路:
    1. 首先定义构造列表和遍历列表的方法(不是必要的)
    2. 利用pre节点 删除当前节点  操作为pre.next = pre.next.next (如果当前节点的值等于val)
    3. 否则指针继续移动
"""
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution(object):
    def removeElements(self, head, val):
        pre = ListNode(0)
        pre.next = head
        temp = pre
        while temp.next != None:
            if temp.next.val == val:
                temp.next = temp.next.next
            else:
                temp = temp.next
        return pre.next
def create_linklist(array): # 构造单链表
    if not array:
        return None
    preNode = ListNode()
    pre = preNode
    for value in array:
        current = ListNode(value)
        pre.next = current

        pre = current
    get_linklist(preNode.next)
    return preNode.next

def get_linklist(head):     # 遍历单链表的元素
    if head == None:
        return head
    temp = head
    res = []
    while temp != None:
        res.append(temp.val)
        temp = temp.next
    # print(f"len: {len(res)}")
    # print(f"linklist: {res}")
    return res
if __name__ == '__main__':
    head = [1, 2, 6, 3, 4, 5, 6]
    val = 6
    head = create_linklist(head)
    solution = Solution()
    head = solution.removeElements(head, val)
    get_linklist(head)
    print(f"head: {head}")

2.3 设计链表

  1. 刷题链接:
    https://leetcode.cn/problems/design-linked-list/description/
    在这里插入图片描述

2. 思路

  1. 初始化pre节点和链表长度len
  2. 对于get, deleteatIndex, addatIndex 首先判断索引是否符合规则 不符合直接返回None或者是-1 遍历到index前一个节点即可
  3. 头插法和尾插入法

3. AC代码

"""
题目: 707. 设计链表
链接: https://leetcode.cn/problems/design-linked-list/description/
思路:
    1. 初始化pre节点和链表长度len
    2. 对于get, deleteatIndex, addatIndex 首先判断索引是否符合规则 不符合直接返回None或者是-1 遍历到index前一个节点即可
    3. 头插法和尾插入法
"""
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class MyLinkedList(object):

    def __init__(self):
        self.pre = ListNode(0)
        self.len = 0

    # 得到链表的长度
    def get_len(self, pre):
        temp = self.pre.next
        len = 0
        while temp != None:
            temp = temp.next
            len += 1
        return len

    # 得到index索引的节点
    def get(self, index):
        """
        :type index: int
        :rtype: int
        """
        if index >= self.len:
            return -1
        temp = self.pre.next
        for i in range(index):
            temp = temp.next
        return temp.val

    # 头插法
    def addAtHead(self, val):
        """
        :type val: int
        :rtype: None
        """
        currentNode = ListNode(val)
        head = self.pre.next
        currentNode.next = head
        self.pre.next = currentNode
        self.len += 1


    # 尾插法
    def addAtTail(self, val):
        """
        :type val: int
        :rtype: None
        """
        tail = self.pre
        tailNode = ListNode(val)
        while tail.next != None:
            tail = tail.next
        tail.next = tailNode
        self.len += 1

    # val插入到index
    def addAtIndex(self, index, val):
        """
        :type index: int
        :type val: int
        :rtype: None
        """
        if index > self.len:
            return None
        temp = self.pre
        for i in range(index):
            temp = temp.next
        valNode = ListNode(val)
        valNode.next = temp.next
        temp.next = valNode
        self.len += 1


    # 删除index位置的节点
    def deleteAtIndex(self, index):
        """
        :type index: int
        :rtype: None
        """
        if index >= self.len:
            return None
        temp = self.pre
        for i in range(index):
            temp = temp.next
        temp.next = temp.next.next

        self.len -= 1

if __name__ == '__main__':
    print("hello solution")

2.4 反转链表 (**)

1. 刷题链接: https://leetcode.cn/problems/reverse-linked-list/
在这里插入图片描述

2.1 (方法一) 思路

  1. 首先遍历一篇将所有节点存入到栈中
  2. 然后依次出战进行赋值构建新的链表

3. (方法一) AC代码

"""
题目: 206. 反转链表
链接: https://leetcode.cn/problems/reverse-linked-list/
思路:
    1. 首先遍历一篇将所有节点存入到栈中
    2. 然后依次出战进行赋值构建新的链表
"""
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution(object):
    def reverseList(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        if not head:
            return None
        stack = []
        while head != None:
            stack.append(head)
            head = head.next
        stack[0].next = None
        res = stack.pop()
        pre = res
        while stack:
            current = stack.pop()
            pre.next = current
            pre = current
        get_linklist(res)
        return res

def create_linklist(array): # 构造单链表
    if not array:
        return None
    head = ListNode(array[0])
    temp = head
    for value in array[1:]:
        current = ListNode(value)
        temp.next = current
        temp = temp.next
    get_linklist(head)
    return head

def get_linklist(head):     # 遍历单链表的元素
    if head == None:
        return head
    temp = head
    res = []
    while temp != None:
        res.append(temp.val)
        temp = temp.next
    print(f"linklist: {res}")
    return res
if __name__ == '__main__':
    head = []
    head = create_linklist(head)
    solution = Solution()
    solution.reverseList(head)

2.2 (方法一) 思路

  1. pre 指向前一个节点 初始话一定要为null
  2. current 指向当前节点
  3. 直接改变指针的指向,
  4. 要注意每次改变时候pre, current指针的变化

3.2 (方法二)AC代码

"""
题目: 206. 反转链表
链接: https://leetcode.cn/problems/reverse-linked-list/
思路:
    pre 指向前一个节点  初始话一定要为null
    current 指向当前节点
    直接改变指针的指向,
    要注意每次改变时候pre, current指针的变化
"""
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution(object):
    def reverseList(self, head):
        if not head:
            return None
        pre = None
        current = head
        while current != None:
            nextNode = current.next
            current.next = pre

            pre = current
            current = nextNode
        # print(f"nextNode: {pre.val}")
        # print(f"nextNode: {nextNode.next.val}")
        # get_linklist(pre)
        return pre

def create_linklist(array): # 构造单链表
    if not array:
        return None
    head = ListNode(array[0])
    temp = head
    for value in array[1:]:
        current = ListNode(value)
        temp.next = current
        temp = temp.next
    get_linklist(head)
    return head

def get_linklist(head):     # 遍历单链表的元素
    if head == None:
        return head
    temp = head
    res = []
    while temp != None:
        res.append(temp.val)
        temp = temp.next
    print(f"linklist: {res}")
    return res
if __name__ == '__main__':
    head = [1,2,3,4,5]
    head = create_linklist(head)
    solution = Solution()
    solution.reverseList(head)

2.5 两两交换链表中的节点 (**)

1. 刷题链接: https://leetcode.cn/problems/swap-nodes-in-pairs/description/
在这里插入图片描述

2. 思路
在这里插入图片描述

3. AC代码

"""
题目: 24. 两两交换链表中的节点
链接: https://leetcode.cn/problems/swap-nodes-in-pairs/description/
思路:
"""
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        print(f"hello world")
        if not head or head.next == None:
            return head
        pre = ListNode()
        res = pre
        current = head
        nextNode = head.next
        while nextNode != None:
            temp = nextNode.next
            pre.next = nextNode
            nextNode.next = current
            current.next = temp

            pre = current
            current = temp
            if temp:
                nextNode = temp.next
            else:
                nextNode = temp
        get_linklist(res.next)
        return res.next

def create_linklist(array):  # 构造单链表
    if not array:
        return None
    preNode = ListNode()
    pre = preNode
    for value in array:
        current = ListNode(value)
        pre.next = current

        pre = current
    get_linklist(preNode.next)
    return preNode.next


def get_linklist(head):  # 遍历单链表的元素
    if head == None:
        return head
    temp = head
    res = []
    while temp != None:
        res.append(temp.val)
        temp = temp.next
    # print(f"len: {len(res)}")
    print(f"linklist: {res}")
    return res
if __name__ == '__main__':
    head = [1, 2, 3, 4]
    head = create_linklist(head)
    solution = Solution()
    solution.swapPairs(head)

2.6 删除链表的倒数第 N 个结点

1. 刷题链接: https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
在这里插入图片描述

2. 思路

  1. 倒数滴n个节点相当于 index = len-n+1
  2. 循环遍历到索引index即可 然后执行删除操作

3. AC代码

"""
题目: 删除链表的倒数第 N 个结点
链接: https://leetcode.cn/problems/remove-nth-node-from-end-of-list/
思路:
    倒数滴n个节点相当于 index = len-n+1
    循环遍历到索引index即可 然后执行删除操作
"""
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution(object):
    def removeNthFromEnd(self, head, n):
        """
        :type head: ListNode
        :type n: int
        :rtype: ListNode
        """
        if not head:
            return head
        len = self.get_len(head)
        index = len - n
        # print(f"index: {index}")
        pre = ListNode()
        res = pre
        pre.next = head
        for i in range(index):
            pre = pre.next
        pre.next = pre.next.next
        # get_linklist(res.next)
        return res.next
    def get_len(self, head):
        temp = head
        len = 0
        while temp != None:
            temp = temp.next
            len += 1
        return len

def create_linklist(array): # 构造单链表
    if not array:
        return None
    preNode = ListNode()
    pre = preNode
    for value in array:
        current = ListNode(value)
        pre.next = current

        pre = current
    get_linklist(preNode.next)
    return preNode.next
def get_linklist(head):     # 遍历单链表的元素
    if head == None:
        return head
    temp = head
    res = []
    while temp != None:
        res.append(temp.val)
        temp = temp.next
    # print(f"len: {len(res)}")
    print(f"linklist: {res}")
    return res
if __name__ == '__main__':
    head = [1, 2, 3, 4, 5]
    n = 2
    solution = Solution()
    head = create_linklist(head)
    solution.removeNthFromEnd(head, n)

2.7 链表相交 (**)

1. 刷题链接: https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/
在这里插入图片描述

2.1 (方法1)思路

  1. 将两个链表都存入到数组中
  2. 然后使得其中一个进行翻转(ListA),
  3. 遍历ListA, 取得ListA中在ListB中的最后一个元素

3.1 (方法1)AC代码

"""
题目: 面试题 02.07. 链表相交
链接: https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/
思路:
    将两个链表都存入到数组中
    然后使得其中一个进行翻转(ListA),
    遍历ListA, 取得ListA中在ListB中的最后一个元素
"""
class ListNode(object):
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
class Solution(object):
    def getIntersectionNode(self, headA, headB):
        """
        :type head1, head1: ListNode
        :rtype: ListNode
        """
        listA = self.get_NodeList(headA)
        listB = self.get_NodeList(headB)
        reversed(listA)
        print(listA)
        print(listB)
        for currentNode in listA:
            if currentNode in listB:
                print(f"currentNode: {currentNode.val}")
                return currentNode

        return None
    def get_NodeList(self, head):
        res_list = []
        temp = head
        while temp != None:
            res_list.append(temp)
            temp = temp.next

        return res_list
def create_linklist(array): # 构造单链表
    if not array:
        return None
    preNode = ListNode()
    pre = preNode
    for value in array:
        current = ListNode(value)
        pre.next = current

        pre = current
    get_linklist(preNode.next)
    return preNode.next
def get_linklist(head):     # 遍历单链表的元素
    if head == None:
        return head
    temp = head
    res = []
    while temp != None:
        res.append(temp.val)
        temp = temp.next
    # print(f"len: {len(res)}")
    print(f"linklist: {res}")
    return res

if __name__ == '__main__':
    listA = [4, 1, 8, 4, 5]
    print(listA.reverse())
    print(listA)
    listB = [5, 0, 1, 8, 4, 5]
    listA = create_linklist(listA)
    listB = create_linklist(listB)
    solution = Solution()
    solution.getIntersectionNode(listA, listB)

2.2 (方法2)思路

  1. 首先翻转两个链表
  2. 找到最后一个相似得节点保存下来进行返回

3.2 (方法2)AC代码

"""
题目: 面试题 02.07. 链表相交
链接: https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/
思路:
    首先翻转两个链表
    找到最后一个相似得节点保存下来进行返回

"""

2.8 环形链表 II

1. 刷题链接: https://leetcode.cn/problems/linked-list-cycle-ii/description/
在这里插入图片描述

2.1 (方法1)思路

  1. 利用一个数组存储节点, 遍历链表节点,不存在则将列表加入数组, 存在说明有环则返回

3.1 (方法1)AC代码

"""
题目: 142. 环形链表 II
链接: https://leetcode.cn/problems/linked-list-cycle-ii/description/
思路:
    利用一个数组存储节点, 遍历链表节点,不存在则将列表加入数组, 存在说明有环则返回
"""
class ListNode(object):
    def __int__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution(object):
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        res_list = []
        current = head
        while current != None:
            if current not in res_list:
                res_list.append(current)
            else:
                return current
            current = current.next
        return -1

2.2 (方法2)思路

  1. 利用一个数组存储节点, 遍历链表节点,不存在则将列表加入数组, 存在说明有环则返回

3.2 (方法2)AC代码

2.9 总结

详细总结:
https://www.programmercarl.com/%E9%93%BE%E8%A1%A8%E6%80%BB%E7%BB%93%E7%AF%87.html#%E9%93%BE%E8%A1%A8%E7%9A%84%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80

3. 哈希表

章节预览:
在这里插入图片描述

3.1 理论基础

详细介绍:https://www.programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html
常见得三种hash数据结构。

  • 数组
  • set (集合)
  • map(映射)

3.2 有效的字母异位词

1. 刷题链接: https://leetcode.cn/problems/valid-anagram/description/
在这里插入图片描述

2. 思路:

利用map解决就行 类似76. 最小覆盖子串这道题目
利用一个requires和map就可以解决
首先将字符串s转化为一个数组, 然后依次遍历t的字符判断,
不存在直接返回False, 存在则减去1, 如果value为0并且require_chars-1

3. AC代码:

"""
题目: 242. 有效的字母异位词
链接: https://leetcode.cn/problems/valid-anagram/description/
思路:
    利用map解决就行 类似76. 最小覆盖子串这道题目
    利用一个requires和map就可以解决
    首先将字符串s转化为一个数组, 然后依次遍历t的字符判断,
    不存在直接返回False, 存在则减去1, 如果value为0并且require_chars-1
"""
class Solution(object):
    def isAnagram(self, s, t):
        """
        :type s: str
        :type t: str
        :rtype: bool
        """
        if len(s) != len(t):
            return False
        s_map = {}
        for char in s:
            s_map[char] = s_map.get(char, 0) + 1
        require_chars = len(s_map)
        for char in t:
            if char in s_map:
                s_map[char] -= 1
                if s_map[char] == 0:    # 等于0 去除
                    require_chars -= 1
                    del s_map[char]
            else:
                return False
        # print(require_chars)
        return require_chars == 0


if __name__ == '__main__':
    s = "anagram"
    t = "nagaram"
    # s = "rat"
    # t = "car"
    solution = Solution()
    res = solution.isAnagram(s, t)
    print(res)

3.3 两个数组的交集

1. 刷题链接:https://leetcode.cn/problems/intersection-of-two-arrays/description/
在这里插入图片描述

2. 思路

  1. 定义res用于存放最终结果
  2. 遍历nums1中的每个元素 如果num在nums2列表中且不存在res 那么res列表加入当前元组
  3. 最终返回res列表

3. AC代码

"""
题目: 349. 两个数组的交集
链接: https://leetcode.cn/problems/intersection-of-two-arrays/description/
思路:
    1. 定义res用于存放最终结果
    2. 遍历nums1中的每个元素 如果num在nums2列表中且不存在res 那么res列表加入当前元组
    3. 最终返回res列表
"""
class Solution(object):
    def intersection(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: List[int]
        """
        res = []
        for num in nums1:
            if num in nums2 and num not in res:
                res.append(num)
        return res

if __name__ == '__main__':
    nums1 = [1, 2, 2, 1]
    nums2 = [2, 2]
    solution = Solution()
    res = solution.intersection(nums1, nums2)
    print(res)

3.4 快乐数

1. 刷题链接: https://leetcode.cn/problems/happy-number/description/
在这里插入图片描述

2. 思路

  1. 创建一个res列表存放在sum数字,首先编写一个通过num得到sum的函数,
  2. 然后利用一个列表加入sum,如果当前sum在res列表中则返回False, 其他情况继续调用isHappy(sum)
  3. 如果1在res中返回True
    sum会重复出现,这对解题很重要!

3. AC代码

"""
题目: 202. 快乐数
链接: https://leetcode.cn/problems/happy-number/description/
思路:
    1. 创建一个res列表存放在sum数字,首先编写一个通过num得到sum的函数,
    2. 然后利用一个列表加入sum,如果当前sum在res列表中则返回False, 其他情况继续调用isHappy(sum)
    3. 如果1在res中返回True
sum会重复出现,这对解题很重要!
"""
class Solution(object):
    def __init__(self):
        self.res = []
    def isHappy(self, n):
        """
        :type n: int
        :rtype: bool
        """
        self.res.append(n)
        current = self.getNumSum(n)
        if 1 in self.res:
            return True
        elif current in self.res:
            return False
        else:
            return self.isHappy(current)

    def getNumSum(self, n):
        sum = 0
        while n > 0:
            temp = n % 10
            n //= 10
            sum = sum + temp * temp
        return sum

if __name__ == '__main__':
    n = 18
    solution = Solution()
    res = solution.isHappy(n)
    print(res)

3.5 两数之和

1. 刷题链接 https://leetcode.cn/problems/two-sum/description/
在这里插入图片描述

2.1 (方法一)思路

  • 最简单的方法就是利用两个for循环遍历即可 但是性能比较低

3.1 (方法一)AC代码

"""
题目: 1. 两数之和
链接: https://leetcode.cn/problems/two-sum/description/
思路:
     最简单的方法就是利用两个for循环遍历即可  但是性能比较低
"""
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

if __name__ == '__main__':
    nums = [2, 7, 11, 15]
    target = 9
    solution = Solution()
    res = solution.twoSum(nums, target)
    print(res)

2.2 (方法二)思路

  1. 利用map记录 key:value=元素值:索引
  2. 依次判断target-元素值 是否在map中 在则直接返回 不在则map[key] = value继续判断

3.2 (方法二)AC代码

"""
题目: 1. 两数之和
链接: https://leetcode.cn/problems/two-sum/description/
思路:
     最简单的方法就是利用两个for循环遍历即可  但是性能比较低
"""
class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

if __name__ == '__main__':
    nums = [2, 7, 11, 15]
    target = 9
    solution = Solution()
    res = solution.twoSum(nums, target)
    print(res)

3.6 四数相加 II

1. 刷题链接: https://leetcode.cn/problems/4sum-ii/
在这里插入图片描述

2. 思路

  1. 三/四层for循环超出时间限制, 两层for循环可以解决
  2. 利用两个map,用两层的for循环进行解决
  3. left_map存放num1, num2的和 元素和:个数
  4. right_map存放num3, num4的和 元素和:个数
  5. 最终判断key, -key是存在 存在则相加计算最终个数

3. AC代码

"""
题目: 四数相加 II
链接: https://leetcode.cn/problems/4sum-ii/
思路:
    三/四层for循环超出时间限制, 两层for循环可以解决
    利用两个map,用两层的for循环进行解决
    left_map存放num1, num2的和  元素和:个数
    right_map存放num3, num4的和  元素和:个数
    最终判断key, -key是存在 存在则相加计算最终个数
"""
class Solution(object):
    def fourSumCount(self, nums1, nums2, nums3, nums4):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :type nums3: List[int]
        :type nums4: List[int]
        :rtype: int
        """
        n = len(nums1)
        res = 0
        left_map = {}
        right_map = {}
        for i in range(n):
            for j in range(n):
                key = nums1[i]+nums2[j]
                left_map[key] = left_map.get(key, 0) + 1
        for k in range(n):
            for l in range(n):
                key = nums3[k] + nums4[l]
                right_map[key] = right_map.get(key, 0) + 1
        # print(left_map)
        # print(right_map)
        for key, value in left_map.items():
            if -key in right_map:
                res = res +  (left_map[key] * right_map[-key])
        return res



if __name__ == '__main__':
    nums1 = [1,2]
    nums2 = [-2,-1]
    nums3 = [-1,2]
    nums4 = [0,2]
    solution = Solution()
    res = solution.fourSumCount(nums1, nums2, nums3, nums4)
    print(res)

3.7 赎金信

1. 刷题链接: https://leetcode.cn/problems/ransom-note/description/
在这里插入图片描述

2. 思路

  1. 将ransonNote转化为map, require_char是需要的长度
  2. 遍历magazine 元素, 如果在map中那么–, 最终判断require_char是否为0从而返回True or False

3. AC代码

"""
题目: 383. 赎金信
链接: https://leetcode.cn/problems/ransom-note/description/
思路:
    1. 将ransonNote转化为map, require_char是需要的长度
    2. 遍历magazine 元素, 如果在map中那么--, 最终判断require_char是否为0从而返回True or False
"""
class Solution(object):
    def canConstruct(self, ransomNote, magazine):
        """
        :type ransomNote: str
        :type magazine: str
        :rtype: bool
        """
        r_map = {}
        for char in ransomNote:
            r_map[char] = r_map.get(char, 0) + 1
        require_char = len(r_map)
        print(require_char)
        print(r_map)
        for char in magazine:
            if char in r_map:
                r_map[char] -= 1
                if r_map[char] == 0:
                    require_char -= 1
                    if require_char == 0:
                        return True
                    del r_map[char]
        return False

if __name__ == '__main__':
    ransomNote = "aa"
    magazine = "aab"
    solution = Solution()
    res = solution.canConstruct(ransomNote, magazine)
    print(res)

3.8 三数之和 (**)

1. 刷题链接 https://leetcode.cn/problems/3sum/
在这里插入图片描述

2. 思路
1. 首先得对nums进行排序
2. 利用双指针 每次遍历nums,遍历i时 左指针和右指针分别为i+1 len(nums)-1
3. 然后就是去重操作 针对i得去重就是 i > 0 and nums[i] == num[i-1]

3. AC代码

"""
题目: 15. 三数之和
链接: https://leetcode.cn/problems/3sum/
思路:
    1. 暴力解法超出时间限制  只能过99%
    2.
        首先得对nums进行排序
        利用双指针 每次遍历nums,遍历i时 左指针和右指针分别为i+1 len(nums)-1
        然后就是去重操作 针对i得去重就是 i > 0 and nums[i] == num[i-1]

"""
class Solution(object):
    def threeSum(self, nums):
        nums.sort()
        res = []
        for i in range(len(nums)-2):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            l = i+1
            r = len(nums) - 1
            while l < r:
                total = nums[i] + nums[l] + nums[r]
                if total == 0:
                    res.append([nums[i], nums[l], nums[r]])
                    # while l < r and nums[l] == nums[l+1]:   # l 去重
                    #     l += 1
                    # while l < r and nums[r] == nums[r-1]:   # r 去重
                    #     r -= 1
                    l += 1
                    r -= 1
                elif total < 0:
                    l += 1
                else:
                    r -= 1
        return res

if __name__ == '__main__':
    nums = [-1, 0, 1, 2, -1, -4]
    solution = Solution()
    res = solution.threeSum(nums)
    print(res)

3.9 四数之和 (**)

1. 刷题链接: https://leetcode.cn/problems/4sum/description/
在这里插入图片描述

2. 思路

  1. 和三数之和类似, 不同之处是需要去重不同
  2. i 去重 if i > 0 and nums[i] == nums[i-1]:
  3. j 去重 j > i+1 and nums[j] == nums[j-1]:

3. AC代码

"""
题目: 18. 四数之和
链接: https://leetcode.cn/problems/4sum/description/
思路:
    和三数之和类似, 不同之处是需要去重不同
    i 去重 if i > 0 and nums[i] == nums[i-1]:
    j 去重 j > i+1 and nums[j] == nums[j-1]:
"""
class Solution(object):
    def fourSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[List[int]]
        """
        nums.sort()
        res = []
        for i in range(len(nums)-3):
            if i > 0 and nums[i] == nums[i-1]:
                continue
            for j in range(i+1, len(nums)-2):
                if j > i+1 and nums[j] == nums[j-1]:                        # 注意这里是i+1而不是1
                    continue
                l = j+1
                r = len(nums) - 1
                while l < r:
                    total = nums[i] + nums[j] + nums[l] + nums[r]
                    if total == target:
                        res.append([nums[i], nums[j], nums[l], nums[r]])
                        while l < r and nums[l] == nums[l+1]:
                            l += 1
                        while l < r and nums[r] == nums[r-1]:
                            r -= 1
                        l += 1
                        r -= 1
                    elif total < target:
                        l += 1
                    else:
                        r -= 1
        return res



if __name__ == '__main__':
    nums = [-2,-1,-1,1,1,2,2]
    target = 0
    solution = Solution()
    res = solution.fourSum(nums, target)
    print(res)

3.10 哈希表总结

详细总结: https://www.programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E6%80%BB%E7%BB%93.html

4. 字符串

样本

1. 刷题链接

2. 思路

3. AC代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/941664.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是亚马逊类目核心关键词?

亚马逊类目核心关键词是指在亚马逊平台上&#xff0c;与特定产品类别相关且具有较高搜索量和竞争度的关键词。这些关键词在产品标题、描述、属性和搜索关键字等位置使用&#xff0c;有助于提高产品的曝光度和搜索排名&#xff0c;并吸引潜在买家的注意。选择适当的核心关键词可…

@Configuration 注解的 Full 模式和 Lite 模式!

Configuration 注解相信各位小伙伴经常会用到&#xff0c;但是大家知道吗&#xff0c;这个注解有两种不同的模式&#xff0c;一种叫做 Full 模式&#xff0c;另外一种则叫做 Lite 模式。 准确来说&#xff0c;Full 模式和 Lite 模式其实 Spring 容器在处理 Bean 时的两种不同行…

Nacos基础(2)——nacos的服务器和命名空间 springBoot整合nacos 多个nacos配置的情况

目录 引出nacos服务器和命名空间Nacos服务器命名空间 springBoot整合nacosspringcloud Alibaba 版本与springcloud对应关系引包配置maincontroller 报错以及解决【报错】错误&#xff1a;缺少服务名称报错&#xff1a;9848端口未开放 启动测试引入多个nacos配置多个配置的情况没…

基于java swing和mysql实现的学生选课成绩信息管理系统(源码+数据库+ER图文档+运行指导视频)

一、项目简介 本项目是一套基于java swing和mysql实现的学生选课成绩信息管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含&#xff1a;项目源码、项目文档、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。…

概念解析 | 无人机集群形状与轨迹建模: 集群舞蹈的艺术

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:无人机集群形状和轨迹建模 无人机集群形状与轨迹建模: 集群舞蹈的艺术 无人机集群的形状和轨迹建模可能听起来像是一部科幻小说的标题,但它实际上是现实中的一个重要研究领…

国内精选五大现货黄金价格实时查询软件最新名单(综合榜单)

随着金融市场的不断发展和投资者的日益增多&#xff0c;现货黄金价格实时查询软件成为了人们关注的焦点。投资者需要一款功能强大、操作简便、数据准确的软件来帮助他们获取实时的黄金价格信息&#xff0c;以便做出更加明智的投资决策。 本文将介绍国内精选五大现货黄金价格实…

iOS - 订阅型内购指南

一、App Store Connect 帮助 二、测试 三、订阅状态 四、问题思考 1、订阅归属&#xff1a; 以往的消耗性内购, 通常会生成订单ID对应到苹果的内购ID及用户id&#xff0c;对于我们来说&#xff0c;内购仅仅只是个支付工具&#xff0c;而订阅型内购有一整套销售模型订阅内购…

zabbix语言无法选择中文--zabbix安装配置中文

You are not able to choose some of the languages, because locales for them are not installed on the web server. 1、安装wget yum -y install wget 2、下载中文中文字体并配置 wget https://github.com/echohn/zabbix-zh_CN/archive/master.zip yum -y install unzip un…

4年经验来面试20K的测试岗,一问三不知,我还真不如去招应届生...

公司前段缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-20k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。看简历很多都是4年工作经验&#xff0c;但面试…

恒运资本:A股三大指数是什么?A股三大指数怎么看?

炒股并不是盲目跟风&#xff0c;投资者自身要了解股票基本常识。例如指数反映的是股票商场上股票的变动状况&#xff0c;能够给我们的投资决策带来一定的依据。那么&#xff0c;A股三大指数是什么&#xff1f;A股三大指数怎么看&#xff1f;恒运资本为我们准备了相关内容&#…

如何给图片加水印?

如何给图片加水印&#xff1f;在我们的日常生活中&#xff0c;许多热爱摄影的朋友都会选择给自己的照片添加水印。这是因为我们深知&#xff0c;一张出色的照片背后需要付出大量的努力和心血&#xff0c;而通过添加水印可以有效地保护自己照片的版权&#xff0c;这样即使将图片…

MySQL概述,架构原理

一.MySQL简介 MySQL是一个关系型数据库管理系统&#xff0c;由瑞典的MySQL AB公司开发&#xff0c;后被oracle公司收购&#xff0c;MySQL是当下最流行的关系型数据库管理系统之一&#xff0c;在WEB应用方面&#xff0c;MySQL是最好的RDBMS&#xff08;Relational Database Man…

得帆信息西区总经理——何龙:低代码初识

企业数字化建设、数字化转型是近年来企业经营管理必然面对的课题&#xff1b;相较于面对传统经营管理的驾车就熟&#xff0c;这无疑给企业管理者提出了新的课题和新的挑战。在当前新技术新生产力不断涌现、新市场特点不断变化的时代&#xff0c;企业在要练好内功、加强经营管理…

龙讯旷腾Q-Studio新增力场优化功能

Q-Studio新功能 Q-Studio&#xff08;在线建模功能&#xff09;依托Mcloud平台免费向用户开放使用&#xff0c;基于jsmol的建模功能无需安装任何软件/插件&#xff0c;通过web端即可在线完成格式转换和可视化建模工作&#xff0c;并可对模型进行个性化的二次编辑&#xff0c;快…

【80天学习完《深入理解计算机系统》】第九天 3.2 数据传送指令【mov】【栈和堆 就是内存】【leaq】【一元操作】【二元操作】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

开源利器推荐:美团动态线程池框架的接入分享及效果展示

前言 蛮早前有些过关于线程池的使用及参数的一些参考配置&#xff0c;有兴趣的可以翻看以前的博文&#xff0c;但终究无法解决线程池的动态监控和实时修改。 以前读过美团早期发布的动态线程池框架的思路相关文章&#xff0c;但想要独自实现不是一件容易的事。 去年&#xff0c…

SpringMVC之RESTful(含实际代码操作)

文章目录 前言一、RESTful简介二、RESTful的实现三、HiddenHttpMethodFilter四、源码实例1.工程文件图2.Employee实体类2.dao层&#xff1a;EmployeeDao类3.首页&#xff1a;index.html4.控制层&#xff1a;EmployeeController类5.employee_add.html页面6.employee_list.html页…

阀门状态监测和预测性维护的原理和实施步骤

随着制造业数字化转型的推进&#xff0c;预测性维护&#xff08;Predictive Maintenance&#xff0c;简称PdM&#xff09;成为提高生产效率和设备可靠性的关键策略之一。在流程工厂中&#xff0c;阀门作为重要的设备之一&#xff0c;起着控制流体流动的关键作用。本文将探讨如何…

基于AVR128单片机智能传送装置

一、系统方案 1、板载可变电阻&#xff08;电位器&#xff09;R29的电压作为处理器ATmega128的模数转换模块中单端ADC0的模拟信号输入&#xff08;跳线JP13短接&#xff09;。 2、调节电位器&#xff0c;将改变AD转换接口ADC0的模拟信号输入&#xff0c;由处理器完成ADC0的A/D转…

积分商城系统源码_积分兑换礼品功能设计_OctShop

礼品系统&#xff1a;礼品需要积分兑换&#xff0c;买家在平台消费&#xff0c;评价商品或店铺赚取积分,商家发布礼品可赚取积分&#xff0c;商家积分可用于奖励买家评价商品。礼品系统和商品库差不多&#xff0c;礼品的发布&#xff0c;修改&#xff0c;展示&#xff0c;库存以…