93.复原IP地址
题目链接:93. 复原 IP 地址 - 力扣(LeetCode)
class Solution {
List<String> ans = new ArrayList<>();
StringBuffer sb = new StringBuffer();
public List<String> restoreIpAddresses(String s) {
backtrack(s, 0, 0);
return ans;
}
private void backtrack(String s,int n,int index) {
if(n == 4 && index == s.length()) {
ans.add(sb.toString().substring(0, sb.length() - 1));
return;
}else if(n == 4 || index == s.length()){
return;
}
for(int i = index; i < s.length() && i < index + 3; ++i) {
if(helper(s.substring(index, i + 1))) {
sb.append(s.substring(index, i + 1));
sb.append('.');
++n;
}else {
continue;
}
backtrack(s, n, i+1);
sb.deleteCharAt(sb.length() - 1);
--n;
for(int j = sb.length() - 1; j >=0; --j) {
if(sb.charAt(j) == '.') {
break;
}else {
sb.deleteCharAt(j);
}
}
}
}
private boolean helper(String str) {
if(str.length() == 1) {
return true;
}
if(str.charAt(0) == '0' || str.length() > 3) {
return false;
}
int b = 0;
for(int i = 0; i < str.length(); ++i) {
b *= 10;
b += str.charAt(i) - '0';
}
return b <= 255;
}
}
78.子集
class Solution {
List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> subsets(int[] nums) {
backtrack(nums, 0, new ArrayList<>());
return ans;
}
private void backtrack(int[] nums, int index,List<Integer> list) {
ans.add(new ArrayList<>(list));
for(int i = index; i < nums.length; ++i) {
list.add(nums[i]);
backtrack(nums, i + 1, list);
list.removeLast();
}
}
}
90.子集II
无剪枝:
class Solution {
Set<List<Integer>> ans = new HashSet();
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
backtrack(nums, 0, new ArrayList<>());
return new ArrayList<>(ans);
}
private void backtrack(int[] nums, int index, List<Integer> list) {
ans.add(new ArrayList<>(list));
for(int i = index; i < nums.length; ++i) {
list.add(nums[i]);
backtrack(nums, i + 1, list);
list.removeLast();
}
}
}
used数组剪枝:
class Solution {
List<List<Integer>> result = new ArrayList<>();// 存放符合条件结果的集合
LinkedList<Integer> path = new LinkedList<>();// 用来存放符合条件结果
boolean[] used;
public List<List<Integer>> subsetsWithDup(int[] nums) {
if (nums.length == 0){
result.add(path);
return result;
}
Arrays.sort(nums);
used = new boolean[nums.length];
subsetsWithDupHelper(nums, 0);
return result;
}
private void subsetsWithDupHelper(int[] nums, int startIndex){
result.add(new ArrayList<>(path));
if (startIndex >= nums.length){
return;
}
for (int i = startIndex; i < nums.length; i++){
if (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]){
continue;
}
path.add(nums[i]);
used[i] = true;
subsetsWithDupHelper(nums, i + 1);
path.removeLast();
used[i] = false;
}
}
}
不适用used数组剪枝:
class Solution {
List<List<Integer>> res = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> subsetsWithDup( int[] nums ) {
Arrays.sort( nums );
subsetsWithDupHelper( nums, 0 );
return res;
}
private void subsetsWithDupHelper( int[] nums, int start ) {
res.add( new ArrayList<>( path ) );
for ( int i = start; i < nums.length; i++ ) {
// 跳过当前树层使用过的、相同的元素
if ( i > start && nums[i - 1] == nums[i] ) {
continue;
}
path.add( nums[i] );
subsetsWithDupHelper( nums, i + 1 );
path.removeLast();
}
}
}