• [leetCode]剑指 Offer 38. 字符串的排列



    在这里插入图片描述

    解法

    • 把字符串(abc)看成两部分:a|bc

      1. 第一个字符 a
      2. 剩余字符 bc
    • 将第一个字符与剩余字符交换,列举出第一个位置所有可能出现的字符(3种: a,b, c)

    • 求第二部分字符串的全排列,第二部分又可以看成两部分:

      1. 第一个字符
      2. 剩余部分

      在这里插入图片描述

      由于是处理相同的问题所以可以递归求解。

    class Solution {
    
        //set集合避免重复
        private Set<String> ans = new HashSet<>();
    
        public String[] permutation(String s) {
            if(s == null || s == ""){
                return new String[]{};
            }
            char[] chars = s.toCharArray();
            permutation(chars, 0);
            String[] a = new String[ans.size()];
            int i = 0;
            for(String each : ans){
                a[i] = each;
                ++i;  
            }
            return a;
        }
    
        private void permutation(char[] chars, int begin){
            if(begin == chars.length){
                ans.add(String.valueOf(chars));
            }else{
                for(int cur = begin; cur < chars.length; ++cur){//第一个字符与后面的字符做交换
                    exch(chars, cur, begin);
                    permutation(chars, begin + 1);//固定第一位字符,求剩余字符的全排列
                    exch(chars, cur, begin);//交换之后换回来
                }
            }
        }
    
        private void exch(char[] chars, int i, int j){
            char temp = chars[i];
            chars[i] = chars[j];
            chars[j] = temp;
        }
    }
    

    类似题目

    组合

    在这里插入图片描述
    在这里插入图片描述

    class Solution {
    
        private List<List<Integer>> output = new LinkedList<>();
    
        private int n;
    
        private int k;
    
        public List<List<Integer>> combine(int n, int k) {
            if(n < k) return new LinkedList();
            this.n = n;
            this.k = k;
            backTrack(1, new LinkedList<Integer>());
            return output;
        }
    
        
        private void backTrack(int begin, LinkedList<Integer> cur){
            if(cur.size() == k){
                output.add(new LinkedList(cur));
            }else {
                for(int i = begin; i < n + 1; ++i){
                    cur.add(i);
                    backTrack(i+1, cur);
                    cur.removeLast();
                }
            }
        }
    
    }
    

    组合总和

    在这里插入图片描述

    class Solution {
    
        private List<List<Integer>> ans = new LinkedList<>();
    
        private int[] candidates;
    
        public List<List<Integer>> combinationSum(int[] candidates, int target) {
            if(candidates == null) return new LinkedList<>();
            this.candidates = candidates;
            backTrack(0, new LinkedList<Integer>(),target);
            return ans;
        }
    
        private void backTrack(int begin, LinkedList<Integer> curr,int target){
            if(target < 0)
                return;
            if(0 == target){
                ans.add(new LinkedList<Integer>(curr));
                return;
            }
            for(int i = begin; i < candidates.length; ++i){
                curr.add(candidates[i]);
                backTrack(i, curr, target - candidates[i]);
                curr.removeLast();
            }
        }
    }
    

    组合总和||

    在这里插入图片描述

    class Solution {
    
        private List<List<Integer>> ans = new LinkedList<>();
    
        private int[] candidates;
    
        public List<List<Integer>> combinationSum2(int[] candidates, int target) {
            if(candidates == null) return new LinkedList<>();
            Arrays.sort(candidates);//先排序
            this.candidates = candidates;
            backTrack(0, new LinkedList<Integer>(),target);
            return ans;
        }
    
        private void backTrack(int begin, LinkedList<Integer> curr,int target){
            if(0 == target){
                ans.add(new LinkedList<Integer>(curr));
                return;
            }
             if (target< 0) {
                    return;
                }
            for(int i = begin; i < candidates.length; ++i){
                if (i > begin && candidates[i] == candidates[i - 1]) {
                    continue;
                }
                curr.add(candidates[i]);
                backTrack(i+1, curr, target - candidates[i]);
                curr.removeLast();
            }
        }
    }
    

    组合总和|||

    在这里插入图片描述

    class Solution {
    
        private List<List<Integer>> ans = new LinkedList<>();
    
        private int k;
    
        public List<List<Integer>> combinationSum3(int k, int n) {
            this.k = k;
            backTrack(1, new LinkedList(), n);
            return ans;
        }
    
        private void backTrack(int begin, LinkedList<Integer> curr, int n){
            if(k == curr.size() && n == 0){
                ans.add(new LinkedList<Integer>(curr));
                return;
            }
            if( n < 0){
                return;
            }
            for(int i = begin; i <= 9; i++){
                curr.add(i);
                backTrack(i+1, curr, n - i);
                curr.removeLast();
            }
        }
    }
    
  • 相关阅读:
    vue input输入框长度限制
    vue中input输入框的模糊查询实现
    腾讯云服务器配置node环境
    axios中的this指向问题
    腾讯云服务器 ubuntu 设置允许root用户登录
    nodejs+express+mongodb写api接口的简单尝试
    通过fromdata实现上传文件
    阿姆斯特朗数
    Mac上webstorm与git仓库建立连接
    iOS学习——属性引用self.xx与_xx的区别
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13859952.html
Copyright © 2020-2023  润新知