动态规划二(子串、子集、全排列、组和)

推荐一篇博客:比较全的动态规划博客

1、Subsquences

打印一个字符串的全部子序列,包括空字符串。

思路

在每一个位置上数,都有两种选择--有或者没有

public class PrintAllSubsquences {
     /**
      * @param str 字符数组-可以是字符串转过来的字符数组
      * @param i   字符数组的下标
      * @param res 上一层传进来的字符串
      */
     public static void PrintAllSubs(char[] str,int  i,String res){
          //停止条件
          if (i == str.length) {
              System.out.println(res); //排列完所有字符打印
              return;
          }
          //打印下一层时不要上一个字符
          PrintAllSubs(str, i + 1, res);
          //打印下一层时要上一个字符
          PrintAllSubs(str, i + 1, res +  String.valueOf(str[i]));
     }
     public static void main(String[] args) {
          String test = "abc";
          PrintAllSubs(test.toCharArray(), 0, "");
     }
}

2、 PermutationsOfSquences

打印字符串的全排列

public class PrintAllPermutations {
//打印全排列
     public static void PrintAll(String string) {
          char[] str = string.toCharArray();
          printProcess(str,0);
     }
     public static void printProcess(char[] str,int i) {
          if (i == str.length) {
              System.out.println(String.valueOf(str));
          }
          //字符串的每一个位置都要和其他位置进行交换
          for (int j = i; j < str.length; j++) {  
              swap(str,i,j);
              printProcess(str, i + 1);
              swap(str,i,j);
          }
     }
     
     public static void swap(char[] str,int i,int j) {
          char temp = str[i];
          str[i] = str[j];
          str[j] = temp;
     }
     public static void main(String[] args) {
          String test = "abc";
          PrintAll(test);
     }
}

78. Subsets

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> alist = new ArrayList<>();
        if(nums.length < 1)
            return alist;
        backTrack(alist,new ArrayList<>(), nums, 0);
        return alist;
    }
    void backTrack(List<List<Integer>> alist, List<Integer> blist, int[] nums, int i){
        if(i == nums.length){
            alist.add(new ArrayList<>(blist));
            return;
        }
        backTrack(alist,blist,nums,i + 1); //要这个值
        blist.add(nums[i]);
        backTrack(alist,blist,nums,i + 1); //不要最后一个
        blist.remove(blist.size() - 1);
    }

90. Subsets II

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: [1,2,2]
Output:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
public List<List<Integer>> subsetsWithDup(int[] nums) {
        Arrays.sort(nums);
		List<List<Integer>> result = new ArrayList<List<Integer>>();
        backTracking2(nums, result, new ArrayList<>(), 0);
        return result;
        
    }
	void backTracking(int[] nums,  List<List<Integer>> alist, List<Integer> blist, int i) {
		if(i == nums.length) {
			if(!alist.contains(blist))
				alist.add(new ArrayList<>(blist));
			return;
		}
		backTracking(nums, alist, blist, i + 1); //要当前值
		blist.add(nums[i]);
		backTracking(nums, alist, blist, i + 1); //不要当前值
		blist.remove(blist.size() - 1);			
	}
    void backTracking2(int[] nums,  List<List<Integer>> alist, List<Integer> blist, int i) {
		if(blist.size() <= nums.length ) { //由于是子集,所以遇到的每一个值都有可能是答案
			alist.add(new ArrayList<>(blist));
		}
		for (int j = i; j < nums.length; j++) {
			if(j > i && nums[j] == nums[j - 1])
				continue;
			blist.add(nums[j]);
			backTracking2(nums, alist, blist, j + 1);
			blist.remove(blist.size() - 1);	
		}
	}

46. Permutations

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
public  List<List<Integer>> permute(int[] nums) {
	        List<List<Integer>> alist = new ArrayList<List<Integer>>();
	        if(nums == null || nums.length < 1)
	        	return alist;
	        Process(alist, new ArrayList<>(), nums);
	        return alist;
	           }
	
    public void Process(List<List<Integer>> blist, List<Integer> clist, int[] nums){
	    if(clist.size() == nums.length){
            blist.add(new ArrayList<>(clist));
            return;
        }	
	    for (int j = 0; j < nums.length; j++) {
		//swap(nums, i, j);
                if(clist.contains(nums[j]))
                    continue;
                clist.add(nums[j]);
	        Process(blist, clist, nums);
                clist.remove(clist.size() - 1);
	     }
	}
	
	public void swap(int[] nums, int i, int j) {
		int tmp = nums[i];
		nums[i] = nums[j];
		nums[j] = tmp;
	}

47. Permutations II

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

Example:

Input: [1,1,2]
Output:
[
  [1,1,2],
  [1,2,1],
  [2,1,1]
]
public List<List<Integer>> permuteUnique(int[] nums) {
		Arrays.sort(nums);
		List<List<Integer>> result = new ArrayList<List<Integer>>();
		boolean[] u = new boolean[nums.length]; 
		backTracking(result, new ArrayList<>(), nums, u);
		return result;
	    }
	
	public void backTracking(List<List<Integer>> alist, List<Integer> blist, 
                             int[] nums, boolean[] used) {
		if(blist.size() == nums.length) {
			alist.add(new ArrayList<>(blist));
			return;
		} 
		for (int i = 0; i < nums.length; i++) {
			if(used[i] || (i > 0 && nums[i] == nums[i - 1] && !used[i - 1]))
				continue;
			used[i] = true;
			blist.add(nums[i]);
			backTracking(alist, blist, nums, used);
			used[i] = false;
			blist.remove(blist.size() - 1);
		}
	}

39. Combination Sum

Given a set of candidate numbers (candidates(without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
  [7],
  [2,2,3]
]

Example 2:

Input: candidates = [2,3,5], target = 8,
A solution set is:
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]
 public List<List<Integer>> combinationSum(int[] candidates, int target) { 
		 Arrays.sort(candidates);
		 List<List<Integer>> result = new ArrayList<List<Integer>>();
		 backTracking(candidates, target, 0, result, new ArrayList<>()); 
		 return result;
	 }
	 private void backTracking(int[] candidates, int target, int start,
                              List<List<Integer>> alist, List<Integer> blist) {
		 if(target == 0) {
			 alist.add(new ArrayList<>(blist));
			 return;
		 }
		 //导致出现重复是由于此处的i又从0开始计算的,
		 //因为i额数组已经排序好了,当走到数组中间的时候前面的已经走过了
		 for (int i = start; i < candidates.length; i++) { 
			 if(candidates[i] <= target) {
				 blist.add(candidates[i]);
				 backTracking(candidates, target - candidates[i], i,alist, blist);
				 blist.remove(blist.size() - 1);
			 }
		}
	 }

40. Combination Sum II

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

Each number in candidates may only be used once in the combination.

Note:

  • All numbers (including target) will be positive integers.
  • The solution set must not contain duplicate combinations.

Example 1:

Input: candidates = [10,1,2,7,6,1,5], target = 8,
A solution set is:
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

Example 2:

Input: candidates = [2,5,2,1,2], target = 5,
A solution set is:
[
  [1,2,2],
  [5]
]
 public List<List<Integer>> combinationSum2(int[] candidates, int target) {
		Arrays.sort(candidates);
		List<List<Integer>> result = new ArrayList<List<Integer>>();
		backTracking(candidates, target, 0, result, new ArrayList<>());
		return result;
    }
	void backTracking(int[] candidates, int target, int i, 
                             List<List<Integer>> alist, List<Integer> blist) {
		
		if(target == 0) {
			alist.add(new ArrayList<>(blist));
			return;
		}//int i = start
		for (; i < candidates.length; i++) {
			if(target < candidates[i]) break;
			blist.add(candidates[i]);
			backTracking(candidates, target - candidates[i], i + 1, alist, blist);
			blist.remove(blist.size() - 1);
			//每次清除一个空位让后续元素加入。寻找成功,最后一个元素要退位,
			//寻找不到,方法不可行,那么我们回退,也要移除最后一个元素。
			while (i < candidates.length - 1 && candidates[i] == candidates[i + 1]) {
				i++;	
			}
		}
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值