1.两数之和
https://leetcode-cn.com/problems/two-sum/
原题
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
提示:
2 <= nums.length <= 10^3
-10^9 <= nums[i] <= 10^9
-10^9 <= target <= 10^9
- 只会存在一个有效答案
标签
数组
哈希表
解答
解题思路
暴力法:两次for循环,时间复杂度
O
(
n
2
)
O(n^2)
O(n2), 空间复杂度
O
(
1
)
O(1)
O(1)
利用哈希表:哈希表查询时间复杂度
O
(
1
)
O(1)
O(1),总的时间复杂度
O
(
n
)
O(n)
O(n),空间复杂度
O
(
n
)
O(n)
O(n), 达到了空间换时间的效果
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hashtable = dict()
for i in range(len(nums)):
if target-nums[i] not in hashtable:
hashtable[nums[i]] = i
else:
return [hashtable[target-nums[i]], i]
return None
237.删除链表中的节点
https://leetcode-cn.com/problems/delete-node-in-a-linked-list/
原题
请编写一个函数,使其可以删除某个链表中给定的(非末尾)节点。传入函数的唯一参数为 要被删除的节点 。
现有一个链表 – head = [4,5,1,9],它可以表示为:
示例 1:
输入:head = [4,5,1,9], node = 5
输出:[4,1,9]
解释:给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.
示例 2:
输入:head = [4,5,1,9], node = 1
输出:[4,5,9]
解释:给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.
提示:
- 链表至少包含两个节点。
- 链表中所有节点的值都是唯一的。
- 给定的节点为非末尾节点并且一定是链表中的一个有效节点。
- 不要从你的函数中返回任何结果。
标签
链表
解答
虽然我们不能delete这个node A,但可以用后面的node B把这个node覆盖掉,然后用它的下下个地址node C来作为node A的下一个地址。我们干掉的其实不是这个node A,而是它的下一个node B,我们本想杀掉的node正披着它的下一个node的外衣活着
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def deleteNode(self, node):
"""
:type node: ListNode
:rtype: void Do not return anything, modify node in-place instead.
"""
node.val = node.next.val
node.next = node.next.next
复杂度分析
- 时间复杂度:O(1)
- 空间复杂度:O(1)
104.二叉树的最大深度
https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
原题
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
标签
树
深度优先搜索
递归
解答
解题思路
方法一:深度优先遍历,利用递归,二叉树的最大深度为1+其左子树和右子树深度中最大者
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root:
return 0
else:
return 1+max(self.maxDepth(root.left),self.maxDepth(root.right))
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(height),树的高度,最坏情况O(n)
方法二:广度优先遍历,每一次遍历完一层深度加1
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root:
return 0
queue = collections.deque([root])
depth = 0
while queue:
n = len(queue)
for i in range(n):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
depth += 1
return depth
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(width),树的宽度,最坏情况O(n)
344.反转字符串
https://leetcode-cn.com/problems/reverse-string/
原题
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[]
的形式给出。
不要给另外的数组分配额外的空间,你必须 原地修改输入数组 、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
示例 2:
输入:["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]
标签
双指针
字符串
解答
解题思路
方法一:分奇数和偶数情况,把关于中点对称的元素互相交换即可
方法二:也可以使用双指针,一个指针从最左往右移动,一个指针从最右往左移动,当相遇或交错位置时停止
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
n = len(s)
if n % 2 == 1:
for i in range(int((n-1)/2)):
s[i],s[n-1-i] = s[n-1-i],s[i]
else:
for i in range(int(n/2)):
s[i],s[n-1-i] = s[n-1-i],s[i]
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(1)
108.将有序数组转换为二叉搜索树
https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/
原题
给你一个整数数组 nums
,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。
高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。
示例 1:
输入:nums = [-10,-3,0,5,9]
输出:[0,-3,9,-10,null,5]
解释:[0,-10,5,null,-3,null,9] 也将被视为正确答案:
<img alt="" src="https://assets.leetcode.com/uploads/2021/02/18/btree2.jpg" style="width: 302px; height: 222px;" />
示例 2:
输入:nums = [1,3]
输出:[3,1]
解释:[1,3] 和 [3,1] 都是高度平衡二叉搜索树。
提示:
1 <= nums.length <= 10^4
-10^4 <= nums[i] <= 10^4
nums
按 严格递增 顺序排列
标签
树
深度优先搜索
解答
解题思路
已经升序好的数组要做成一颗平衡的二叉搜索树,关键在于要把排序在中点的中位数作为根节点,然后小于中位数的作为左子树,大于中位数的作为右子树,对于这两颗子树也要以此规律找根节点
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
n = len(nums)
def make_tree(start_index,end_index):
if start_index > end_index:
return None
else:
mid_index = (end_index+start_index)//2
this_tree_root = TreeNode(nums[mid_index])
this_tree_root.left = make_tree(start_index,mid_index-1)
this_tree_root.right = make_tree(mid_index+1,end_index)
return this_tree_root
return make_tree(0,n-1)
复杂度分析
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组的长度。每个数字只访问一次
空间复杂度: O ( log n ) O(\log n) O(logn),其中 n n n 是数组的长度。空间复杂度不考虑返回值,因此空间复杂度主要取决于递归栈的深度,递归栈的深度是 O ( log n ) O(\log n) O(logn)