经典时尚算法题思路
-
两数之和(Two Sum)
-
问题描述:给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。
-
解决方法:使用哈希表存储每个数及其索引,遍历数组,对于每个数,检查目标值减去该数的差是否在哈希表中。
-
-
反转链表(Reverse Linked List)
-
问题描述:反转一个单链表。
-
解决方法:迭代或递归。迭代时,维护三个指针:前一个节点、当前节点、下一个节点。
-
-
有效的括号(Valid Parentheses)
-
问题描述:给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
-
解决方法:使用栈,遇到左括号入栈,遇到右括号则检查栈顶是否匹配。
-
-
合并两个有序链表(Merge Two Sorted Lists)
-
问题描述:将两个升序链表合并为一个新的升序链表。
-
解决方法:递归或迭代。迭代时,比较两个链表的当前节点,将较小的节点连接到结果链表。
-
-
最大子数组和(Maximum Subarray)
-
问题描述:给定一个整数数组,找出一个具有最大和的连续子数组。
-
解决方法:动态规划(Kadane算法)。遍历数组,对于每个元素,决定是将其加入当前子数组还是开始新的子数组。
-
-
爬楼梯(Climbing Stairs)
-
问题描述:每次可以爬1或2个台阶,到达n阶楼梯有多少种不同方法。
-
解决方法:动态规划。dp[i] = dp[i-1] + dp[i-2],初始条件dp[0]=1, dp[1]=1。
-
-
二叉树的中序遍历(Binary Tree Inorder Traversal)
-
问题描述:给定一个二叉树,返回它的中序遍历。
-
解决方法:递归或使用栈迭代。
-
-
二叉树的层次遍历(Binary Tree Level Order Traversal)
-
问题描述:给定一个二叉树,返回其节点值的层次遍历。
-
解决方法:使用队列进行BFS。
-
-
最长公共子序列(Longest Common Subsequence)
-
问题描述:给定两个字符串,找出它们的最长公共子序列。
-
解决方法:动态规划。dp[i][j]表示text1[0:i]和text2[0:j]的最长公共子序列长度。
-
-
最长递增子序列(Longest Increasing Subsequence)
-
问题描述:给定一个整数数组,找到其中最长严格递增子序列的长度。
-
解决方法:动态规划(O(n^2))或贪心+二分查找(O(n log n))。
-
-
股票买卖问题(Best Time to Buy and Sell Stock)
-
问题描述:给定一个数组,第i个元素是第i天的股票价格,设计算法来获取最大利润。
-
解决方法:一次遍历,记录历史最低点,然后计算每天卖出能获得的最大利润。
-
-
打家劫舍(House Robber)
-
问题描述:给定一个数组,表示每个房屋的金额,不能抢劫相邻的房屋,求最大金额。
-
解决方法:动态规划。dp[i] = max(dp[i-1], dp[i-2] + nums[i])。
-
-
岛屿数量(Number of Islands)
-
问题描述:给定一个由 '1'(陆地)和 '0'(水)组成的二维网格,计算岛屿的数量。
-
解决方法:DFS或BFS。遍历网格,遇到陆地时进行DFS/BFS标记所有相连的陆地。
-
-
括号生成(Generate Parentheses)
-
问题描述:给定n对括号,生成所有有效的括号组合。
-
解决方法:回溯。递归时记录当前字符串以及左右括号的数量。
-
-
全排列(Permutations)
-
问题描述:给定一个没有重复数字的序列,返回其所有可能的全排列。
-
解决方法:回溯。交换元素,递归,再交换回来。
-
-
LRU缓存(LRU Cache)
-
问题描述:设计一个LRU缓存,支持get和put操作。
-
解决方法:使用哈希表+双向链表。哈希表存储键到节点的映射,双向链表维护访问顺序。
-
-
实现Trie(前缀树)(Implement Trie (Prefix Tree))
-
问题描述:实现一个Trie,包含insert, search, 和 startsWith操作。
-
解决方法:每个节点包含一个子节点数组(或哈希表)和一个标志表示是否为单词结尾。
-
-
数组中的第K个最大元素(Kth Largest Element in an Array)
-
问题描述:在未排序的数组中找到第k个最大的元素。
-
解决方法:快速选择算法(基于快速排序的分区思想)或使用堆。
-
-
滑动窗口最大值(Sliding Window Maximum)
-
问题描述:给定一个数组和一个滑动窗口的大小,找出所有滑动窗口里的最大值。
-
解决方法:使用双端队列维护一个递减序列,队列头部为当前窗口最大值。
-
-
最小路径和(Minimum Path Sum)
-
问题描述:给定一个包含非负整数的m x n网格,找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
-
解决方法:动态规划。dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])。
-
以上是一些经典题目,覆盖了数组、链表、树、动态规划、回溯、堆、栈、队列等常见数据结构和算法。在准备秋招时,建议不仅理解这些题目的解法,还要能够举一反三,掌握算法思想。
数组/字符串类
两数之和
python
def twoSum(nums, target):
hashmap = {}
for i, num in enumerate(nums):
complement = target - num
if complement in hashmap:
return [hashmap[complement], i]
hashmap[num] = i
return []
链表类
迭代和递归
python
# 迭代解法
def reverseList(head):
prev, curr = None, head
while curr:
next_temp = curr.next
curr.next = prev
prev = curr
curr = next_temp
return prev
# 递归解法
def reverseListRecursive(head):
if not head or not head.next:
return head
new_head = reverseListRecursive(head.next)
head.next.next = head
head.next = None
return new_head
二叉树的层序遍历
python
def levelOrder(root):
if not root:
return []
result = []
queue = collections.deque([root])
while queue:
level_size = len(queue)
current_level = []
for _ in range(level_size):
node = queue.popleft()
current_level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(current_level)
return result
最长递增子序列
python
def lengthOfLIS(nums):
if not nums:
return 0
dp = [1] * len(nums)
for i in range(1, len(nums)):
for j in range(i):
if nums[i] > nums[j]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
背包问题
python
# 0-1背包
def knapsack(weights, values, capacity):
n = len(weights)
dp = [[0] * (capacity + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for w in range(1, capacity + 1):
if weights[i-1] <= w:
dp[i][w] = max(dp[i-1][w],
dp[i-1][w-weights[i-1]] + values[i-1])
else:
dp[i][w] = dp[i-1][w]
return dp[n][capacity]
全排列
python
def permute(nums):
def backtrack(path, used):
if len(path) == len(nums):
result.append(path[:])
return
for i in range(len(nums)):
if not used[i]:
used[i] = True
path.append(nums[i])
backtrack(path, used)
path.pop()
used[i] = False
result = []
backtrack([], [False] * len(nums))
return result
冒泡排序
python
def bubble_sort(arr):
n = len(arr)
# 进行n-1轮比较
for i in range(n - 1):
# 每轮将最大的元素"冒泡"到最后
for j in range(n - 1 - i):
if arr[j] > arr[j + 1]:
# 交换相邻元素
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr