93.复原IP地址
public class Solution {
List<string> result=new List<string>();
public IList<string> RestoreIpAddresses(string s) {
if(s.Length>12)
{
return result;
}
backtracking(s,0,0);
return result;
}
public void backtracking(string s,int startIndex,int pointsum)
{
if(pointsum==3)
{
if(Isvalid(s,startIndex,s.Length-1))
{
result.Add(s);
}
return;
}
for(int i=startIndex;i<s.Length;i++)
{
if(Isvalid(s,startIndex,i))
{
s=s.Substring(0,i+1)+"."+s.Substring(i+1);
pointsum++;
backtracking(s,i+2,pointsum);
pointsum--;
s=s.Substring(0,i+1)+s.Substring(i+2);
}else
{
break;
}
}
}
public bool Isvalid(string s,int start,int end)
{
if(start>end)
{
return false;
}
if(s[start]=='0'&&start!=end)
{
return false;
}
int num=0;
for(int i=start;i<=end;i++)
{
if(s[i]>'9'||s[i]<'0')
{
return false;
}
num=num*10+(s[i]-'0');
if(num>255)
{
return false;
}
}
return true;
}
}
本题的结束条件就是Ip地址的分割点为3个就收集Path,但是除了这个还要判断是否地址合理在0-255的范围内,如果合法就打上分隔符,然后递归,然后回溯,最终返回所收集到的结果。
78.子集
public class Solution {
List<int> path=new List<int>();
List<IList<int>> result=new List<IList<int>>();
public IList<IList<int>> Subsets(int[] nums) {
backtracking(nums,0);
return result;
}
public void backtracking(int[] nums,int startIndex)
{
result.Add(new List<int>(path));
for(int i=startIndex;i<nums.Length;i++)
{
path.Add(nums[i]);
backtracking(nums,i+1);
path.RemoveAt(path.Count-1);
}
}
}
自己收进Path的条件是直接收集就行,但要注意Startindex的取值是I+1,因为不能有重复的。
90.子集II
public class Solution {
List<int> path=new List<int>();
List<IList<int>> result=new List<IList<int>>();
bool[] used;
public IList<IList<int>> SubsetsWithDup(int[] nums) {
used=new bool[nums.Length];
for(int i=0;i<used.Length;i++)
{
used[i]=false;
}
Array.Sort(nums);
backtracking(nums,0,used);
return result;
}
public void backtracking(int[] nums,int startIndex,bool[] used)
{
result.Add(new List<int>(path));
for(int i=startIndex;i<nums.Length;i++)
{
if (i>0&&nums[i]==nums[i-1]&&used[i-1]==false)
{
continue;
}
path.Add(nums[i]);
used[i]=true;
backtracking(nums,i+1,used);
used[i]=false;
path.RemoveAt(path.Count-1);
}
}
}
在上一题的基础上加入了一个Used的Bool类型数组,因为我们需要在树层上剪枝,树枝上保留,所以如果当树层向下遇到了两个相邻的相同元素,就去看前一个的Used数组是否为False,如果是就跳过,否则就加入Path,最终返回即可。