60 Permutation Sequence 字典序第k个排列
Input: n = 3, k = 3
Output: “213”
康拓展开:计算排列与字典序排名的映射关系
32 下一个排列
思路:
1)找到最后非递增的子数组725321 -> 5321 已经是这4个数字排列的最大值了。
2)只能增大前面的72,从5321中挑一个比2大最少的数交换,增量最小。
3)交换完后变成5221反转一下变成最小。
1 | public void nextPermutation(int[] nums) { |
139 word break 用字典中的此能否拆分字符串
输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以被拆分成 “apple pen apple”。
注意你可以重复使用字典中的单词。
memory方法1:用set记录不能划分的位置
memory方法2:用set记录划分过的单词
9ms 77%
1 | public boolean wordBreak(String s, List<String> wordDict) { |
1.状态:boolean[n+1]长度为i的前缀能否由字典组成
2.初始值:[0]=true 空字符串
3.转移方程if(dp[i]==true&&dic.contains(sub(i,i+j))) dp[i+j]=true
4.结果
6ms 88%1
2
3
4
5
6
7
8
9
10
11
12
13
14public boolean wordBreak(String s, List<String> wordDict) {
int n = s.length();
boolean[] cb = new boolean[n+1];
cb[0] = true;
for(int k = 1;k < n + 1;k++){
for(int st = 0;st < k;st++){
if(cb[st] && wordDict.contains(s.substring(st,k))){
cb[k] = true;
break;
}
}
}
return cb[n];
}
90 有重复的subset[1,2,2,2]
- 选不同的2得到{1,2}是重复的
- 次序不同得到{1,2},{2,1}是重复的
先排序,再去重。
关键:i!=idx
当[2,2]idx+1那次不应该被去重
1 | public List<List<Integer>> subsetsWithDup(int[] nums) { |
还有一种迭代计数的方法//todo
78 subset 数组的子集
1 | public List<List<Integer>> subsets(int[] nums) { |
位运算迭代:1
2
3
4
5
6
7
8
9
10
11
12
13
14public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> rst = new ArrayList<>();
int n = nums.length;
for(int i = 0;i<(1<<n);i++){
List<Integer> tmp = new ArrayList<>();
for(int j = 0;j<n;j++){
if(((i>>j)&1)==1){
tmp.add(nums[j]);
}
}
rst.add(tmp);
}
return rst;
}