专题3:字符串 / 数组排列

字符串/数组排列

1.把数组排成最小的数(剑指Offer 45)

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

代码思想:

排列的思想都是取一个比较一次,最好用的工具就是系统自带的比较器,只需重写compare方法即可。

代码实现:

public String PrintMinNumber(int[] numbers) {
        if (numbers == null || numbers.length == 0) return "";
        String[] str = new String[numbers.length];
        for (int i = 0; i < numbers.length; i++) {
            str[i] = String.valueOf(numbers[i]);
        }
        Arrays.sort(str, new Comparator() {
            @Override
            public int compare(String o1, String o2) {
                return (o1 + o2).compareTo(o2 + o1);
            }
        });
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length; i++) {
            sb.append(str[i]);
        }
        return sb.toString();
    }

2.字典序排数(LeetCode386)

给定一个整数 n, 返回从 到 的字典顺序。

例如,给定 n =1 3,返回 [1,10,11,12,13,2,3,4,5,6,7,8,9] 

代码思想:字典序是假设每次比较两个串,依次从第一个字符比较(按数字或字母的顺序),再比较下一个字符。如果两个字符串长度不相等,则将短的字符串补全,补的元素是当前排序规则中最小的元素(比如0或者‘a’)。

字典序排数仍然采用比较器进行两两对比。

代码实现:

public List lexicalOrder(int n) {
        List res = new ArrayList<>();
        if (n < 1 || n > 5000000) return res;
        List list = new ArrayList<>();
        for (int i = 1; i <= n; i++) {
            list.add(String.valueOf(i));
        }
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(String a, String b) {
                return a.compareTo(b);
            }
        });
        for (int i = 0; i < n; i++) {
            res.add(Integer.valueOf(list.get(i)));
        }
        return res;
    }

3.数全排列(LeetCode46)

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

输入: [1,2,3]
输出:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

代码思想:将过程看成两步:

  • 第一步:所有可能出现在第一个数字的位置,即将原数组的第一个数字与后面的数字依次交换。
  • 第二步:固定第一个数字,数组后面部分重复第一步。

直至数组遍历结束,递归完成。

代码实现:

List> res = new ArrayList<>();
    private int len = 0;

    public List> permute(int[] nums) {
        len = nums.length;
        if (len == 0) return res;
        int index = 0;
        permutation(nums, index);
        return res;
    }

    public void permutation(int[] nums, int index) {
        if (index == len) {
            int tmp = 0;
            List list = new ArrayList<>();
            while (tmp < len) {
                list.add(nums[tmp++]);
            }
            res.add(list);
        } else {
            for (int i = index; i != len; ++i) {
                swap(nums, i, index);
                permutation(nums, index + 1);
                swap(nums, i, index);
            }
        }
    }

    public void swap(int[] nums, int a, int b) {
        int tmp = nums[a];
        nums[a] = nums[b];
        nums[b] = tmp;
    }

拓展题目:字符全排列(剑指Offer 38)

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

代码思想:这道题相对于数字全排列多了一个按照字典序排列,只要把最后结果利用比较器重新排序一下即可。

代码实现:

ArrayList list = new ArrayList<>();
    private int len = 0;

    public ArrayList Permutation(String str) {
        len = str.length();
        if (len == 0) return list;
        list =  permute(str.toCharArray(), 0);
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        return list;
    }

    public ArrayList permute(char[] str, int index) {
        if (index == len) {
            String res = "";
            for (int i = 0; i < len; i++) {
                res += str[i];
            }
            if(!list.contains(res))   list.add(res);
        } else {
            for (int i = index; i != len; i++) {
                swap(str, i, index);
                permute(str, index + 1);
                swap(str, i, index);
            }
        }
        return list;
    }

    public void swap(char[] str, int a, int b) {
        char tmp = str[a];
        str[a] = str[b];
        str[b] = tmp;
    }

代码优化:

public ArrayList Permutation(String str) {
       ArrayList list = new ArrayList();
       if(str!=null&&str.length()>0){
           PermutationHelper(str.toCharArray(),0,list);
       }else{
           return list;
       }
       Collections.sort(list);
       return list;
   }
    public static void PermutationHelper(char[] chars,int i, ArrayList list){
        if(i==chars.length-1){
            String str = String.valueOf(chars);
            if(!list.contains(str)){
                list.add(str);
            }
        }else{
            for(int j=i;j

 

你可能感兴趣的:(算法)