目录:

  1. No.1 两数之和
  2. No.2 两数相加
  3. No.20 有效的括号
  4. No.21 合并两个有序链表
  5. No.22 括号生成
  6. No.24 两两交换链表中的节点
  7. No.27 移除元素
  8. No.35 搜索插入位置

1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

def two_sum(nums, target):
    for i in range(0, len(nums)):
        val2 = (target - nums[i])
        if val2 in nums:
            return i, nums.index(val2, i+1)
    return False

总结:这道题可以说是leetcode最简单的题了,但其实我还是找了一些python的技巧的代码,比如index(x, start, end)。很多题看似简单,其实是因为你会一些方法,但是考试中,你是无法去查这些方法的,这就是刷题的意义所在。你必须把每个知识点吃透。

2. 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

def add_two_numbers(l1, l2):
    l1.reverse()
    l2.reverse()
    n1 = ''.join([str(i) for i in l1])
    n2 = ''.join([str(i) for i in l2])
    n = int(n1) + int(n2)
    li = [int(i) for i in str(807)]
    li.reverse()
    print(li)
def add_two_numbers2(l1, l2):
    total = 0
    next1 = 0
    result = ListNode()
    cur = result

    while (l1 is not None) and (l2 is not None):
        total = l1.val + l2.val + next1
        cur.next = ListNode(total % 10)
        next1 = total // 10
        l1 = l1.next
        l2 = l2.next
        cur = cur.next

    while l1 is not None:
        total = l1.val + next1
        cur.next = ListNode(total % 10)
        next1 = total // 10
        l1 = l1.next
        cur = cur.next

    while l2 is not None:
        total = l2.val + next1
        cur.next = ListNode(total % 10)
        next1 = total // 10
        l2 = l2.next
        cur = cur.next

    if next1 != 0:
        cur.next = ListNode(next1)

    return result.next

总结:这道题是我第一次做链表相关的实战题,还是觉得挺难的。这道题也可以用递归的方式做,我没有写。

20. 有效的括号
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
def isValid(s):
    if s == "":
        return True
    stack = []
    
    for i in s:
        if i == "(" or i == "[" or i == "{":
            stack.append(i)
        else:
            if len(stack) == 0:
                return False
            else:
                temp = stack.pop()
                if temp == "(" and i != ")":
                    return False
                elif temp == "[" and i != "]":
                    return False
                elif temp == "{" and i != "}":
                    return False
                    
    return True if len(stack) == 0 else False

总结:我一开始想到了双指针,但是最后用了老师写的堆栈。这个方法的精妙之处在于括号是两两对应的。所以pop出来的值,就是上一个值。另外注意可以利用堆栈pop后,里面的元素是出来的特征,进行设计。

21. 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。
新链表是通过拼接给定的两个链表的所有节点组成的。
方法一:迭代法

def mergeTwoLists(l1, l2):
    result = ListNode()
    cur = result

    while l1 is not None and l2 is not None:
        if l1.val <= l2.val:
            cur.next = l1
            l1 = l1.next
        else:
            cur.next = l2
            l2 = l2.next
        cur = cur.next

    if l1 is None:
        cur.next = l2
    elif l2 is None:
        cur.next = l1

    return result.next

总结:cur = cur.next这个游标没有进行更新,导致输出的结果是一个数字4,说明我之前的输出结果都被覆盖点了。第二个错误是最后return result而没有return result.next。注意是result.next指向的cur。

方法二:递归

def mergeTwoLists2(l1, l2):
    if l1 is None or l2 is None:
        return l1 or l2

    if l1.val <= l2.val:
        l1.next = mergeTwoLists2(l1.next, l2)
        return l1
    elif l2.val < l1.val:
        l2.next = mergeTwoLists2(l1, l2.next)
        return l2

总结:这个递归没有用cur游标,而是一直都是两个链表的互相调用。我是没想到的,照着代码写的。

22. 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
有效括号组合需满足:左括号必须以正确的顺序闭合。

def generateParenthesis(n: int):
    if n <= 0:
        return ""
    res = []

    def dfs(path, left, right):
        if (left > n) or (right > n) or (left < right):
            return
        if len(path) == n * 2:
            res.append(path)
            return

        dfs(path + "(", left + 1, right)
        dfs(path + ")", left, right + 1)

    dfs("", 0, 0)
    return res

24. 两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

def swapPairs(head):
    res = ListNode()
    res.next = head
    first = res

    while (first is not None) and (first.next is not None) and (first.next.next is not None):

        second = first.next
        third = second.next

        first.next = third
        second.next = third.next
        third.next = second

        #  first 后移2位,整体都会后移
        first = first.next.next

    return res.next

27. 移除元素
给你一个数组 nums和一个值 val,你需要 原地 移除所有数值等于val的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

def removeElement(nums, val):
    if len(nums) == 0 or nums is None:
        return 0

    left = 0
    right = len(nums) - 1

    while left < right:
        while left < right and nums[left] != val:
            left += 1
        while left < right and nums[right] == val:
            right -= 1
        nums[left], nums[right] = nums[right], nums[left]

    return left if nums[left] == val else left + 1

35. 搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。
如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。

def searchInsert3(nums, target):
    left, right = 0, len(nums) - 1
    while left < right:
        mid = (left + right) // 2
        if target < nums[mid]:
            right = mid - 1
        elif target > nums[mid]:
            left = mid + 1
        elif target == nums[mid]:
            return mid
    if target > nums[left]:
        return left + 1
    else:
        return left