目录:
- No.1 两数之和
- No.2 两数相加
- No.20 有效的括号
- No.21 合并两个有序链表
- No.22 括号生成
- No.24 两两交换链表中的节点
- No.27 移除元素
- 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 ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
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