回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
1.题目:
Given two integers n and k, return all possible combinations of knumbers out of 1 ... n.
For example,
If n = 4 and k = 2, a solution is:
[ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]思路:
1.创建一个全局变量保存结果。
2.创建一个函数用于递归,传入的变量有,n,k(list中现在还差几个),start(从哪里开始),list(局部变量)
3.递归结束条件:当k<0时返回。当k==0时说明局部变量满足,放入全局变量后返回
4.递归部分: list中存入新值,调用本身,删除存入的心值。
代码:
import java.util.*;
public class Solution {
ArrayList> ret = new ArrayList>();
public ArrayList> combine(int n, int k) {
ArrayList list = new ArrayList();
helper(n,k,1,list);
return ret;
}
public void helper(int n, int k, int start, ArrayList list)
{
if(k < 0 )
return;
if( k==0)
{
ret.add(new ArrayList(list));
}
else
{
for(int i=start; i<=n; i++)
{
list.add(i);
helper(n, k-1, i+1, list);
list.remove(list.size() - 1);
}
}
}
}
Given a set of distinct integers, S, return all possible subsets.
Note:
For example,
If S =[1,2,3], a solution is:
[ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], []
]
using System;
using System.Collections.Generic;
namespace subsets
{
class Program
{
static List> ret = new List>();
static void Main(string[] args)
{
List list = new List();
int[] num = {1,2,3};
Array.Sort(num);
for (int i = 0; i <= num.Length; i++)
{
helper(num, i,0,list);
}
//打印 ret
}
static void helper(int[] num, int k, int start, List list)
{
if (k < 0)
return;
if (k == 0)
{
ret.Add(list);
}
else
{
for (int i = start; i < num.Length; i++)
{
list.Add(num[i]);
helper(num, k - 1, i + 1, list);
list.RemoveAt(list.Count -1);
}
}
}
}
}
using System;
namespace 乔治小木棍
{
class Program
{
static void Main(string[] args)
{
string line;
string[] p;
while ((line = Console.ReadLine()) != "0")
{
int n = int.Parse(line);
p = Console.ReadLine().Trim().Split(' ');
int[] num = new int[n];
int sumLen = 0;//小木棍总长度
for (int i = 0; i < n; i++)
{
num[i] = int.Parse(p[i]);
sumLen += num[i];
}
for (int i = 0; i < n; i++)
{
for (int j = n - 1; j > i; j--)
{
if (num[j] > num[j - 1])
{
int temp = num[j];
num[j] = num[j - 1];
num[j - 1] = temp;
}
}
}
int curLen = num[0]; //检查当前长度是否满足条件,最小长度为最大的木棍长度
bool[] flag = new bool[n]; //记录相对应位置小木棍否被使用过
flag[0] = true;
while (curLen <= sumLen)
{
if (sumLen % curLen == 0)
{
if(dfs(num, flag, n, sumLen - num[0], curLen, num[0]))
break;
}
curLen++;
}
Console.WriteLine(curLen);
}
}
public static bool dfs(int[] num, bool[] flag, int n, int sumLen, int curLen, int left)
{
if (sumLen == 0)
return true;
if (curLen == left)
left = 0;
for (int i = 0; i < n; i++)
{
if (!flag[i])
{
if (left + num[i] == curLen)
{
flag[i] = true;
if (dfs(num, flag, n, sumLen - num[i], curLen, 0))
return true;
flag[i] = false;
return false;
}
else if (left + num[i] < curLen)
{
flag[i] = true;
if (dfs(num, flag, n, sumLen - num[i], curLen, left + num[i]))
return true;
flag[i] = false;
if (left == 0)
return false;
while (i+1
1.典型的回溯法,用递归进行探索。
2.传递的参数包括:root //当前节点. ,expectNumber //期望值 ,sum//当前总数, list //当前遍历过的节点, ret //保存所有路径的容器
3.只有当满足期望值且左右子节点为空时才是期望的路径。
代码:
using System.Collections.Generic;
/*
public class TreeNode
{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode (int x)
{
val = x;
}
}*/
class Solution
{
public List> FindPath(TreeNode root, int expectNumber)
{
// write code here
List> ret = new List>();
dfs(root,expectNumber,0,new List(),ret);
return ret;
}
public void dfs(TreeNode root,int expectNumber,int sum,List list, List> ret)
{
if(root == null)
return;
sum += root.val;
list.Add(root.val);
if(sum == expectNumber && root.left ==null && root.right==null)
{
ret.Add(new List(list));
}
else if(sum < expectNumber)
{
dfs(root.left,expectNumber,sum,list,ret);
dfs(root.right,expectNumber,sum,list,ret);
}
list.RemoveAt(list.Count -1);
}
}
using System.Collections.Generic;
class Solution
{
public List Permutation(string str)
{
// write code here
List list = new List();
char[] chars = str.ToCharArray();
helper(chars, 0, list);
list.Sort();
return list;
}
public void helper(char[] chars, int i, List list)
{
if(i == chars.Length-1)
{
list.Add(new string(chars));
}
else
{
for(int j=i; j