【剑指Offer】32.把数组排成最小的数

题目描述

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

知识点:

  • 数组,全排列,排序,贪心

方法一:暴力破解

  • 假设n个整数的索引值为[0,1,…,n-1],对这n个索引全拍了,再对每次全排列进行一次组织结果,选取最小的值为答案。
  • 时间复杂度:O(n*n!),全排列时间复杂度为N!,每次排列结果需要遍历一次nums数组
  • 空间复杂度:O(1)
  • 代码为:
class Solution {
public:
    void perm(int pos, vector<int> &num, string &ret) {
        if (pos + 1 == num.size()) {
            // 一次全排列的结果
            string tmp = "";
            for (int val : num) {
                tmp += to_string(val);
            }
            ret = min(ret, tmp);
            return;
        }
        for (int i = pos; i < num.size(); ++i) {
            swap(num[pos], num[i]);
            perm(pos+1, num, ret);
            swap(num[pos], num[i]);
        }
    }
    string PrintMinNumber(vector<int> nums) {
        string ret(nums.size(), '9'); // nums.size()个'9'
        perm(0, nums, ret);
        return ret;
    }
};

方法二:贪心,自定义排序

  • 方法一出现太多无关排列,如果存在字符串 a,b。a+b<b+a,则我们希望a在b前。可以自定义排序规则。
  • 时间复杂度:O(nlogn),采用了排序
  • 空间复杂度:O(n)
  • 代码:
class Solution {
public:
    string PrintMinNumber(vector<int> nums) {
        vector<string> str;
        for (int val : nums) str.push_back(to_string(val));
        sort(str.begin(), str.end(), [](string a, string b) {
            return a + b < b + a;
        });
        string ret = "";
        for (string s : str) ret += s;
        return ret;
    }
};

Java实现自定义排序

  • 两次循环,外循环确定每个下标,内存换用来将外循环确定下标元素进行比较。小则冒泡,大则不变。
    public String PrintMinNumber(int [] numbers) {
        ArrayList<String> list = new ArrayList();
        int num1;
        int num2;
        int tmp;
        for (int i = 0; i< numbers.length - 1; i++){
            for (int j = i+1; j < numbers.length; j++){
                num1 = Integer.valueOf(String.valueOf(numbers[i])+String.valueOf(numbers[j]));
                num2 = Integer.valueOf(numbers[j] + ""+numbers[i]);
                if (num1 > num2){
                    tmp = numbers[j];
                    numbers[j] = numbers[i];
                    numbers[i] = tmp;
                }
            }
        }
        String str = "";
        for (int t : numbers){
            str += String.valueOf(t);
        }

        return str;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值