大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn
491. 递增子序列
题目描述
给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。
示例:
输入: [4, 6, 7, 7]
输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]]
说明:
- 给定数组的长度不会超过15。
- 数组中的整数范围是 [-100,100]。
- 给定数组中可能包含重复数字,相等的数字应该被视为递增的一种情况。
分析
dp 解法(类似 bfs)
- 加入当前数字会产生哪些新序列,只要遍历当前存在的序列并比较最后一个数字和当前数字,如果当前数字更大则加入产生新的序列
- 由 1 产生的新序列加上已经存在的序列以及当前数字作为一个新序列起点的情况作为新的结果
- 利用HashSet对list去重
- 最后过滤掉长度不足 2 的序列得到最终结果
/**
* nums = [4, 6, 7, 7]
*
* [4] [4]
* [4,6] [4,6],[4],[6]
* [4,6,7] [4,6,7],[4,7],[6,7],[4,6],[4],[6],[7]
* [4,6,7,7] [4,6,7,7],[6,7,7],[4,7,7],[7,7],[4,6,7],[6,7],[4,7],[7],[4,6,7],[6,7],[4,7],[7],[4,6],[6],[4]
*
*
* result => [4,6,7,7],[6,7,7],[4,7,7],[7,7],[4,6,7],[6,7],[4,7],[4,6]
*/
public List<List<Integer>> findSubsequences(int[] nums) {
Set<List<Integer>> dp = new HashSet<>();
Set<List<Integer>> beforeDp;
for (int i = 0; i < nums.length; i++) {
beforeDp = new HashSet<>(dp);
for (List<Integer> before : beforeDp) {
if(nums[i] >= before.get(before.size()-1)) { //加上新追加的列表
List<Integer> temp = new ArrayList<>(before);
temp.add(nums[i]);
dp.add(temp);
}
dp.add(before); //加上之前的列表
}
dp.add(Arrays.asList(nums[i])); //加上当前元素的
}
return dp.stream().filter(list -> list.size() >= 2).collect(Collectors.toList());
}
dfs 解法(递归回溯+剪枝)
/**
* 考虑 nums={1,2,3}
*
* holder 的输出(不考虑剪枝和递增):
* [1]
* [1, 2]
* [1, 2, 3]
* [1, 2, 3, 3]
* [1, 2, 3, 3, 2]
* [1, 2, 3, 3, 2, 3]
* [1, 2, 3, 3, 2, 3, 3]
*
* holder 的输出(考虑剪枝和递增):
* [1]
* [1, 2]
* [1, 2, 3]
* [1, 3]
* [2]
* [2, 3]
* [3]
*
* result的结果
* [[1, 2, 3], [1, 2], [2, 3], [1, 3]]
*/
public List<List<Integer>> findSubsequences(int[] nums) { // 递归回溯(dfs) + 剪枝。只处理递增子序列,限制只取List大小>=2,并利用HashSet对List去重。
List<Integer> holder = new ArrayList<>();
Set<List<Integer>> result = new HashSet<>();
dfs(0, nums, holder, result);
return new ArrayList<>(result);
}
private void dfs(int index, int[] nums, List<Integer> holder, Set<List<Integer>> result) {
if(holder.size() >= 2) {
result.add(new ArrayList<>(holder));
}
for (int k = index; k < nums.length; k++) {
if (holder.isEmpty() || nums[k] >= holder.get(holder.size() - 1)) { // 限制只处理 递增子序列
holder.add(nums[k]);
dfs(k + 1, nums, holder, result);
holder.remove(holder.size() - 1);
}
}
}
提交结果
2020年8月25日更
大家觉得写还可以,可以点赞、收藏、关注一下吧!
也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn