237.删除链表中的节点
很容易陷入的误区是考虑直接修改指针,但是由于不知道要删除结点的前一个结点,所以不能完成单纯的指针操作。因此我们可以考虑直接交换节点的val,也能达到相同的效果。
# 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
238.除自身以外数组的乘积
此题考查的实际上就是指针的前向遍历和后向遍历,此处给出一个空间复杂度非最优的方法。
使用一个二维数组(或者两个一维数组)来分别存储前向累乘和后向累乘,然后再相乘得到结果。
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
n = len(nums)
# 二维数组,第一个元素记录前向乘积,后一个记录后向的(分两个数组来记录也可以)
temp = [[1] * 2 for _ in range(n + 1)]
# temp[i + 1][0]记录的是直到下标i的元素的前向累乘
for i in range(n):
temp[i + 1][0] = temp[i][0] * nums[i]
# temp[i][1]记录的是直到下标i的元素的后向累乘
for i in range(n - 1, -1, -1):
temp[i][1] = temp[i + 1][1] * nums[i]
output = [0] * n
for i in range(n):
# 这里的错位宏观上其实也很好理解,前向越往后越大,后向越往前越大,
# output是少一个数字的乘积,因此错位的时候让两者都小一点就对了,
# 因此前向要比后向少1
output[i] = temp[i][0] * temp[i + 1][1]
return output
时间复杂度O(n)
,空间复杂度O(n)
。
292.Nim游戏
脑筋急转弯题目,详细解析参考:Nim游戏
class Solution:
def canWinNim(self, n: int) -> bool:
return n % 4 != 0
时间复杂度O(1)
,空间复杂度O(1)
。
344.反转字符串
双指针从两端向中间移动即可,移动的过程中交换字符串中的元素。
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
n = len(s)
left, right = 0, n - 1
while left < right:
s[left], s[right] = s[right], s[left]
left, right = left + 1, right -1
557.反转字符串中的单词
解法一:使用python
内置函数
class Solution:
def reverseWords(self, s: str) -> str:
temp_list = s.split() # 以空格为分解符将s切分为list
for i in range(len(temp_list)):
temp_list[i] = temp_list[i][::-1] # 遍历list的同时将单词反转
return ' '.join(temp_list) # list转换为string
时间复杂度O(n)
,空间复杂度O(n)
。
解法二:空间优化
class Solution:
def reverseWords(self, s: str) -> str:
ans = ''
temp = ''
n = len(s)
for i, ch in enumerate(s):
if ch != ' ': # 存储每个单词
temp += ch
else: # 遇到空格时(一个单词结束)更新ans
ans += (temp[::-1] + ' ')
temp = ''
ans += temp[::-1]
return ans
时间复杂度O(n)
,空间复杂度O(1)
。只使用常数空间temp
来存储一个单词。