LeetCode 解题思路 45(Hot 100)
解题思路:
- dp 数组的含义: 在数组中是否存在一个子集,其和为 i。
- 递推公式: dp[i] |= dp[i - num]。
- dp 数组初始化: dp[0] = true。
- 遍历顺序: 从大到小去遍历,从 i = target 开始,直到 i = num。确保每个数只用一次。
- 打印 dp 数组
Java代码:
class Solution {public boolean canPartition(int[] nums) {int sum = 0;for (int num : nums)sum += num;if (sum % 2 != 0)return false;int target = sum / 2;boolean[] dp = new boolean[target + 1];dp[0] = true;for (int num : nums) {for (int i = target; i >= num; i--) {dp[i] |= dp[i - num];}}return dp[target];}
}
复杂度分析:
- 时间复杂度: O(n * target)。
- 空间复杂度: O(target)。
解题思路:
可以使用栈来解决这个问题。核心思想是利用栈来跟踪未匹配的括号的索引。初始化时,栈中压入一个基准索引 -1,用于后续计算有效子串的长度。遍历字符串时:
- 遇到左括号 ‘(’,将其索引压入栈中。
- 遇到右括号 ‘)’,弹出栈顶元素。此时:
- 若栈为空,说明当前右括号无匹配,将当前索引压入栈作为新基准。
- 若栈不为空,当前有效子串长度为当前索引与栈顶元素的差值,更新最大值。
此方法确保每次弹出栈顶后,栈顶元素即为最近未匹配的左括号或基准点,从而快速计算有效长度。
Java代码:
public class Solution {public int longestValidParentheses(String s) {Deque<Integer> stack = new ArrayDeque<>();stack.push(-1);int maxLen = 0;for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == '(') {stack.push(i);} else {stack.pop();if (stack.isEmpty()) {stack.push(i);} else {maxLen = Math.max(maxLen, i - stack.peek());}}}return maxLen;}
}
复杂度分析:
- 时间复杂度: O(n)。
- 空间复杂度: O(n)。