深度优先搜索(DFS) — 20180926
用DFS的场景:
找出所有方案:DFS
找出所有方案总数 可能是动态规划
DFS时间复杂度:答案个数*构造每个答案的时间
动态规划时间复杂度:状态个数*计算每个状态时间
二叉树时间复杂度:节点数*处理每个节点时间
135. Combination Sum
public class Solution {
/**
* @param candidates: A list of integers
* @param target: An integer
* @return: A list of lists of integers
*/
public List<List<Integer>> combinationSum(int[] candidates, int target) {
// write your code here
List<List<Integer>> result = new ArrayList<>();
if(candidates == null || candidates.length ==0){
return result;
}
Arrays.sort(candidates);
ArrayList<Integer> combination = new ArrayList<>();
Hepler(result,candidates,target,0,combination);
return result;
}
public void Hepler(List<List<Integer>> result,int[] candidates, int target, int startIndex,List<Integer> combination){
if(target == 0){
result.add(new ArrayList(combination));
return;
}
for(int i= startIndex; i<candidates.length; i++){
if(target<candidates[i]){
continue;
}
if(i>0 && candidates[i]==candidates[i-1]){
continue;
}
combination.add(candidates[i]);
Hepler(result,candidates,target-candidates[i],i,combination);
combination.remove(combination.size()-1);
}
}
}
153. Combination Sum II
public class Solution {
/**
* @param num: Given the candidate numbers
* @param target: Given the target number
* @return: All the combinations that sum to target
*/
public List<List<Integer>> combinationSum2(int[] num, int target) {
// write your code here
List<List<Integer>> result = new ArrayList<>();
if(num == null || num.length ==0){
return result;
}
Arrays.sort(num);
List<Integer> combination = new ArrayList<>();
Helper(num,target,0,result,combination);
return result;
}
public void Helper(int[] num, int target, int startIndex, List<List<Integer>> result, List<Integer> combination){
if(target==0){
result.add(new ArrayList<>(combination));
return;
}
for(int i = startIndex; i<num.length; i++){
if(target<num[i]){
break;
}
if(i>0 && num[i] == num[i-1] && i!=startIndex){
continue;
}
combination.add(num[i]);
Helper(num,target-num[i],i+1,result,combination);
combination.remove(combination.size()-1);
}
}
}
136. Palindrome Partitioning
切割问题也就是组合问题
public class Solution {
/*
* @param s: A string
* @return: A list of lists of string
*/
public List<List<String>> partition(String s) {
// write your code here
List<List<String>> result = new ArrayList<>();
if (s == null || s.length() == 0) {
return result;
}
List<String> combination = new ArrayList<>();
Helper(result, combination, 0, s);
return result;
}
public void Helper(List<List<String>> result, List<String> combination, int startIndex, String s) {
if (startIndex == s.length()) {
result.add(new ArrayList<>(combination));
return;
}
for (int i = startIndex; i < s.length(); i++) {
String sub = s.substring(startIndex, i + 1);
if (!isPalindrome(sub)) {
continue;
}
combination.add(sub);
Helper(result, combination, i + 1, s);
combination.remove(combination.size() - 1);
}
}
public boolean isPalindrome(String s) {
int start = 0;
int end = s.length() - 1;
while (start < end) {
if (s.charAt(start) != s.charAt(end)) {
return false;
}
start++;
end--;
}
return true;
}
}
15. Permutations
public class Solution {
/*
* @param nums: A list of integers.
* @return: A list of permutations.
*/
public List<List<Integer>> permute(int[] nums) {
// write your code here
List<List<Integer>> result = new ArrayList<>();
if (nums == null) {
return result;
}
boolean[] visited = new boolean[nums.length];
List<Integer> permutation = new ArrayList<>();
Helper(result, permutation, nums, visited);
return result;
}
public void Helper(List<List<Integer>> result, List<Integer> permutation, int[] nums, boolean[] visited) {
if (permutation.size() == nums.length) {
result.add(new ArrayList<>(permutation));
return;
}
for (int i = 0; i < nums.length; i++) {
if (visited[i]) {
continue;
}
permutation.add(nums[i]);
visited[i] = true;
Helper(result, permutation, nums, visited);
permutation.remove(permutation.size() - 1);
visited[i] = false;
}
}
}
16. Permutations II
public class Solution {
/*
* @param : A list of integers
* @return: A list of unique permutations
*/
public List<List<Integer>> permuteUnique(int[] nums) {
// write your code here
List<List<Integer>> result = new ArrayList<>();
if(nums == null){
return result;
}
List<Integer> permutation = new ArrayList<>();
boolean[] visited =new boolean[nums.length];
Arrays.sort(nums);
Helper(result,nums,permutation,visited);
return result;
}
public void Helper(List<List<Integer>> result, int[] nums, List<Integer> permutation, boolean[] visited){
if(permutation.size() == nums.length){
result.add(new ArrayList<>(permutation));
return;
}
for(int i =0; i<nums.length;i++){
if(visited[i]){
continue;
}
if(i>0 && nums[i]==nums[i-1] && visited[i-1] == false){
continue;
}
permutation.add(nums[i]);
visited[i] = true;
Helper(result,nums,permutation,visited);
permutation.remove(permutation.size()-1);
visited[i] = false;
}
}
};
33. N-Queens
public class Solution {
/*
* @param n: The number of queens
* @return: All distinct solutions
*/
public List<List<String>> solveNQueens(int n) {
// write your code here
List<List<String>> result = new ArrayList<>();
if (n < 0) {
return result;
}
List<Integer> queenSolution = new ArrayList<>();
Helper(result, queenSolution, n);
return result;
}
public void Helper(List<List<String>> result, List<Integer> queenSolution, int n) {
if (queenSolution.size() == n) {
result.add(getQueenStr(queenSolution));
return;
}
for (int i = 0; i < n; i++) {
if (!isValid(queenSolution, i)) {
continue;
}
queenSolution.add(i);
Helper(result, queenSolution, n);
queenSolution.remove(queenSolution.size() - 1);
}
}
public boolean isValid(List<Integer> queenSolution, int q) {
int nextcol = queenSolution.size();
for (int i = 0; i < queenSolution.size(); i++) {
//判断是否同一列
if (queenSolution.get(i) == q) {
return false;
}
//判断是否在左斜线
if (nextcol + q == i + queenSolution.get(i)) {
return false;
}
//判断是否在右斜线
if (nextcol - q == i - queenSolution.get(i)) {
return false;
}
}
return true;
}
public List<String> getQueenStr(List<Integer> solution) {
List<String> res = new ArrayList<>();
int strLen = solution.size();
for (Integer i : solution) {
StringBuilder stringBuilder = new StringBuilder();
for (int m = 0; m < strLen; m++) {
stringBuilder.append(m == i ? 'Q' : '.');
}
res.add(stringBuilder.toString());
}
return res;
}
}
121. Word Ladder II
public class Solution {
/*
* @param start: a string
* @param end: a string
* @param dict: a set of string
* @return: a list of lists of string
*/
public List<List<String>> findLadders(String start, String end, Set<String> dict) {
// write your code here
List<List<String>> result = new ArrayList<>();
if (start == null || end == null) {
return result;
}
if (start.equals(end)) {
List<String> solution = new ArrayList<>();
solution.add(start);
solution.add(end);
result.add(solution);
return result;
}
//字典要加入start,end,否则对某些case会fail
dict.add(start);
dict.add(end);
Map<String, Integer> distanceMap = new HashMap<>();
Map<String, List<String>> neighbourMap = new HashMap<>();
getShortestPath(start, end, dict, distanceMap, neighbourMap);
List<String> solution = new ArrayList<>();
//基于nextWord进行递归,所以一开始要将初始值加入solution
solution.add(start);
Helper(result, solution, distanceMap, neighbourMap, start, end);
return result;
}
//bfs 重点注意,得到最短路径之后一定要走完最后一层的BFS,否则会少解
public void getShortestPath(String start, String end, Set<String> dict,
Map<String, Integer> distanceMap, Map<String, List<String>> neighbourMap) {
Queue<String> queue = new LinkedList<>();
queue.offer(start);
distanceMap.put(start, 0);
int distance = 0;
boolean isShortedPath = false;
while (!queue.isEmpty()) {
int size = queue.size();
distance++;
for (int i = 0; i < size; i++) {
String word = queue.poll();
if (neighbourMap.containsKey(word)) {
continue;
}
neighbourMap.put(word, new ArrayList<>());
for (String next : getNextWords(word, dict)) {
neighbourMap.get(word).add(next);
if(!distanceMap.containsKey(next)){
distanceMap.put(next, distance);
queue.offer(next);
}
if (next.equals(end)) {
isShortedPath = true;
}
}
}
if(isShortedPath){
break;
}
}
}
//dfs
public void Helper(List<List<String>> result, List<String> solution,
Map<String, Integer> distanceMap, Map<String, List<String>> neighbourMap,
String word, String end) {
if(word.equals(end)){
result.add(new ArrayList<>(solution));
return;
}
if(neighbourMap.get(word)!=null){
for(String str: neighbourMap.get(word)){
if(distanceMap.containsKey(str) && distanceMap.get(str) == distanceMap.get(word) + 1){
solution.add(str);
Helper(result,solution,distanceMap,neighbourMap,str,end);
solution.remove(solution.size()-1);
}
}
}
}
public List<String> getNextWords(String word, Set<String> dict) {
List<String> result = new ArrayList<>();
int len = word.length();
for (int i = 0; i < len; i++) {
for (char ch = 'a'; ch <= 'z'; ch++) {
if (ch == word.charAt(i)) {
continue;
}
if (dict.contains(getReplaceWord(word, i, ch))) {
result.add(getReplaceWord(word, i, ch));
}
}
}
return result;
}
public String getReplaceWord(String word, int i, char ch) {
char[] chars = word.toCharArray();
chars[i] = ch;
return new String(chars);
}
}
深度优先搜索(DFS) — 20180926的更多相关文章
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...
- 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)
需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析
转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ...
- 【算法入门】深度优先搜索(DFS)
深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ...
- 深度优先搜索 DFS 学习笔记
深度优先搜索 学习笔记 引入 深度优先搜索 DFS 是图论中最基础,最重要的算法之一.DFS 是一种盲目搜寻法,也就是在每个点 \(u\) 上,任选一条边 DFS,直到回溯到 \(u\) 时才选择别的 ...
- 深度优先搜索(DFS)
[算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一 ...
- 算法总结—深度优先搜索DFS
深度优先搜索(DFS) 往往利用递归函数实现(隐式地使用栈). 深度优先从最开始的状态出发,遍历所有可以到达的状态.由此可以对所有的状态进行操作,或列举出所有的状态. 1.poj2386 Lake C ...
- HDU(搜索专题) 1000 N皇后问题(深度优先搜索DFS)解题报告
前几天一直在忙一些事情,所以一直没来得及开始这个搜索专题的训练,今天做了下这个专题的第一题,皇后问题在我没有开始接受Axie的算法低强度训练前,就早有耳闻了,但一直不知道是什么类型的题目,今天一看,原 ...
- [LeetCode OJ] Word Search 深度优先搜索DFS
Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ...
随机推荐
- WIN XP蓝屏代码大全
转自:廊坊师范学院信息技术提高班---韩正阳 http://blog.csdn.net/jiudihanbing WIN XP蓝屏代码大全WIN XP蓝屏代码大全一.蓝屏含义 1.故障检查信息 *** ...
- Java Random、ThreadLocalRandom、UUID类中的方法应用(随机数)
1.Random:产生一个伪随机数(通过相同的种子,产生的随机数是相同的): Random r=new Random(); System.out.println(r.nextBoolean()); S ...
- (一)在HTML页面中实现一个简单的Tab
在HTML页面中实现一个简单的Tab 为了充分利用有限的HTML页面空间,经常会采用类似与TabControl的效果通过切换来显示更多的内容.本文将采用一种最为简单的方法来实现类似如Tab页切换的效果 ...
- POJ1062 昂贵的聘礼(带限制的spfa)
Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低 ...
- MongoDB整理笔记の新增Shard Server
1.启动一个新Shard Server 进程 [root@localhost ~]# mkdir /data/shard/s2 [root@localhost ~]# /Apps/mongo/bin/ ...
- Fragment生命周期及在viewpager中的生命周期
简介 本篇博客主要从一下三个方面介绍fragement的生命周期 1.fragment的生命周期及与Activity的生命周期的比较 2.FrameLayou布局添加.替换Fragment时fragm ...
- hibernate的获取session的两方法比较,和通过id获取对象的比较,一级缓存二级缓存
opensession与currentsession的联系与区别 在同一个线程中opensession的session是不一样的,而currentsession获取的session是一样的,这就保证了 ...
- HTML5移动开发即学即用(双色) 王志刚 pdf扫描版
HTML5已经广泛应用于各智能移动终端设备上,而且绝大部分技术已经被各种最新版本的测览器所支持:逐一剖析HTML5标准中包含的最新技术,详细介绍了HTML5新标准中提供的各种API,各种各样的应用实例 ...
- C# 的 Task、Thread、ThreadPool 之间有什么异同?
Thread就是Thread,需要自己调度,适合长跑型的操作. ThreadPool是Thread基础上的一个线程池,目的是减少频繁创建线程的开销.线程很贵,要开新的stack,要增加CPU上下文切换 ...
- c++多线程基础4(条件变量)
条件变量是允许多个线程相互交流的同步原语.它允许一定量的线程等待(可以定时)另一线程的提醒,然后再继续.条件变量始终关联到一个互斥 定义于头文件 <condition_variable> ...