经典例题
经典例题:
1、求两个链表的第一个公共节点
思路:
两个链表长度分别为L1+C、L2+C, C为公共部分的长度,
第一个人走了L1+C步后,回到第二个人起点走L2步;
第2个人走了L2+C步后,回到第一个人起点走L1步。
当两个人走的步数都为L1+L2+C时就两个家伙就相遇。
隐藏条件,第一个公共的节点后面的所有节点都相同。公共节点只能链表尾部
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution_52:
def getIntersectionNode(self, headA: ListNode, headB: ListNode)->ListNode:
"""
获取两个链表的第一个公共节点
要求:时间复杂度为O(n), 空间复杂度为O(1)
"""
node1, node2 = headA, headB
while node1 != node2:
node1 = node1.next if node1 else headB
node2 = node2.next if node2 else headA
return node1
2、将整数数组中的奇数和偶数进行分离,奇数在前,偶数在后
思路: 使用双指针,前指针从左往右走, 后指针从右往左走,
前指针遇到偶数停止,后指针遇到奇数停止,然后交换。
class Solution:
def exchange(self, nums: List[int]) -> List[int]:
"""
使用双指针
"""
i, j = 0, len(nums) - 1
while i < j:
while i < j and nums[i] & 1 == 1:
i += 1
while i < j and nums[j] & 1 == 0:
j -= 1
nums[i], nums[j] = nums[j], nums[i]
return nums
Note: 奇偶的数的判断使用位运算&
来进行,
类型:搜索和回溯问题
3 在给定的矩阵中,判断字符是否存在
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
思路:
一般使用深度优先+减枝的方法
class Solution:
def exist(self, board: List[List[str]], word: str) -> bool:
rows = len(board)
cols = len(board[0])
def dfs(i, j, k):
"""
深度优先
"""
# 出去条件:
# 1,不在边界条件之内;
if not 0 <= i < rows:
return False
if not 0 <= j < cols:
return False
# 2,对应字符不相等
if board[i][j] != word[k]:
return False
# 3,符合条件
if k == len(word) - 1:
return True
# 访问过了的网格改为空
board[i][j] = ''
# 节点的访问方向有四个,上下左右
res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)
board[i][j] = word[k]
return res
for i in range(rows):
for j in range(cols): # 遍历矩阵找到开始的字符
if dfs(i, j, 0): # 进行深度优先,搜索查找对应的str
return True
return False