diff --git a/problems/0131.分割回文串.md b/problems/0131.分割回文串.md index f50f1c1d..10b747cb 100644 --- a/problems/0131.分割回文串.md +++ b/problems/0131.分割回文串.md @@ -450,6 +450,38 @@ var partition = function(s) { }; ``` +## TypeScript + +```typescript +function partition(s: string): string[][] { + function isPalindromeStr(s: string, left: number, right: number): boolean { + while (left < right) { + if (s[left++] !== s[right--]) { + return false; + } + } + return true; + } + function backTracking(s: string, startIndex: number, route: string[]): void { + let length: number = s.length; + if (length === startIndex) { + resArr.push(route.slice()); + return; + } + for (let i = startIndex; i < length; i++) { + if (isPalindromeStr(s, startIndex, i)) { + route.push(s.slice(startIndex, i + 1)); + backTracking(s, i + 1, route); + route.pop(); + } + } + } + const resArr: string[][] = []; + backTracking(s, 0, []); + return resArr; +}; +``` + ## C ```c diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md index c8d9bc04..b24fb365 100644 --- a/problems/0416.分割等和子集.md +++ b/problems/0416.分割等和子集.md @@ -208,6 +208,75 @@ class Solution { } ``` +```java +public class Solution { + public static void main(String[] args) { + int num[] = {1,5,11,5}; + canPartition(num); + + } + public static boolean canPartition(int[] nums) { + int len = nums.length; + // 题目已经说非空数组,可以不做非空判断 + int sum = 0; + for (int num : nums) { + sum += num; + } + // 特判:如果是奇数,就不符合要求 + if ((sum %2 ) != 0) { + return false; + } + + int target = sum / 2; //目标背包容量 + // 创建二维状态数组,行:物品索引,列:容量(包括 0) + /* + dp[i][j]表示从数组的 [0, i] 这个子区间内挑选一些正整数 + 每个数只能用一次,使得这些数的和恰好等于 j。 + */ + boolean[][] dp = new boolean[len][target + 1]; + + // 先填表格第 0 行,第 1 个数只能让容积为它自己的背包恰好装满 (这里的dp[][]数组的含义就是“恰好”,所以就算容积比它大的也不要) + if (nums[0] <= target) { + dp[0][nums[0]] = true; + } + // 再填表格后面几行 + //外层遍历物品 + for (int i = 1; i < len; i++) { + //内层遍历背包 + for (int j = 0; j <= target; j++) { + // 直接从上一行先把结果抄下来,然后再修正 + dp[i][j] = dp[i - 1][j]; + + //如果某个物品单独的重量恰好就等于背包的重量,那么也是满足dp数组的定义的 + if (nums[i] == j) { + dp[i][j] = true; + continue; + } + //如果某个物品的重量小于j,那就可以看该物品是否放入背包 + //dp[i - 1][j]表示该物品不放入背包,如果在 [0, i - 1] 这个子区间内已经有一部分元素,使得它们的和为 j ,那么 dp[i][j] = true; + //dp[i - 1][j - nums[i]]表示该物品放入背包。如果在 [0, i - 1] 这个子区间内就得找到一部分元素,使得它们的和为 j - nums[i]。 + if (nums[i] < j) { + dp[i][j] = dp[i - 1][j] || dp[i - 1][j - nums[i]]; + } + } + } + for (int i = 0; i < len; i++) { + for (int j = 0; j <= target; j++) { + System.out.print(dp[i][j]+" "); + } + System.out.println(); + } + return dp[len - 1][target]; + } +} +//dp数组的打印结果 +false true false false false false false false false false false false +false true false false false true true false false false false false +false true false false false true true false false false false true +false true false false false true true false false false true true +``` + + 二维数组版本(易于理解): ```Java class Solution { diff --git a/problems/0509.斐波那契数.md b/problems/0509.斐波那契数.md index 638bfdfe..d339940c 100644 --- a/problems/0509.斐波那契数.md +++ b/problems/0509.斐波那契数.md @@ -277,7 +277,30 @@ int fib(int n){ return fib(n-1) + fib(n-2); } ``` +### Rust +动态规划: +```Rust +pub fn fib(n: i32) -> i32 { + let n = n as usize; + let mut dp = vec![0; 31]; + dp[1] = 1; + for i in 2..=n { + dp[i] = dp[i - 1] + dp[i - 2]; + } + dp[n] +} +``` - +递归实现: +```Rust +pub fn fib(n: i32) -> i32 { + //若n小于等于1,返回n + f n <= 1 { + return n; + } + //否则返回fib(n-1) + fib(n-2) + return fib(n - 1) + fib(n - 2); +} +``` -----------------------