解題思路:
- 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)。