目录
刷题日期:下午8:45 2021年5月10日星期一
个人刷题记录,代码收集,来源皆为leetcode
经过多方讨论和请教,现在打算往Java方向发力
主要答题语言为Java
题目:
剑指 Offer 45. 把数组排成最小的数
难度中等208
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1:
输入: [10,2]
输出: "102"
示例 2:
输入: [3,30,34,5,9]
输出: "3033459"
提示:
0 < nums.length <= 100
说明:
- 输出结果可能非常大,所以你需要返回一个字符串而不是整数
- 拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
题目分析
同样是有规律可循的,要让拼起来更小肯定是每一位都有尽量小,而且对于二位数、三位数还要确定是自己摆上去小,还是其他数值上没它小,但是只存在更大下一位的情况。
排序好像起不到太大的帮助,主要还是看每一位的大小。
盲猜一个数组转字符串,Integer.toString
其实还是一个排序的过程,只不过排序的依据不是传统的大小,而是各位数字在0~9上的大小。比如1000都要比2小,另外相同的话参考第二个示例的30和3。
初始解答:
也只能有些简单的猜想了,参考他人,用到了自己从来没见过的方法,先是调用内置排序函数的版本,全是自己没听说过的骚操作。
class Solution {
public String minNumber(int[] nums) {
//定义一个列表,方使用lambda方法,里面的数据为字符串类型
List<String> list = new ArrayList<>();
//遍历一遍
for(int num : nums) {
//String.valueOf、toString、(String)
list.add(String.valueOf(num)); //由基本数据型态转换成String
//反向转换 int : Integer.parseInt(String s) : 将 s 转换成 int
}
//一个 lambda表达式,意思是: x 和 y 比较大小的原则为: x+y 和 y+x 比大小
list.sort((o1, o2) -> (o1 + o2).compareTo(o2 + o1));
//String.join连接指定数组的元素或集合的成员,在每个元素或成员之间使用指定的分隔符。
return String.join("", list); //将List<string> 转换为 字符串:
}
}
执行结果:通过
显示详情 添加备注
执行用时:8 ms, 在所有 Java 提交中击败了35.23%的用户
内存消耗:38 MB, 在所有 Java 提交中击败了71.65%的用户
快排放在后面单独复习一下,多看几次总能记得住,真正机试时肯定能调库就调库,手撕时就看熟练度了,不行用冒泡也不丢人。
学习他人:
方法一:
…L1 2020-02-16
class Solution {
public String minNumber(int[] nums) {
List<String> list = new ArrayList<>();
for (int num : nums) {
list.add(String.valueOf(num));
}
list.sort((o1, o2) -> (o1 + o2).compareTo(o2 + o1));
return String.join("", list);
}
}
方法二:
白也 (编辑过)2020-06-04 Java lambda一行 好长的一行
class Solution {
public String minNumber(int[] nums) {
return IntStream.of(nums).mapToObj(String::valueOf).sorted(((o1, o2) -> (o1 + o2).compareTo(o2 + o1))).collect(Collectors.joining());
}
}
方法三:
(编辑过)2020-03-12
学习了java的lambda,comparator。这题很够了。
最早的,使用Collections的sort方法+Comparator匿名内部类
Collections.sort(listStr,new Comparator<String>(){
public int compare(String s1, String s2){
return (s1+s2).compareTo(s2+s1);
}
});
Java8的新特性 lambda表达式(闭包)
Collections.sort(listStr,(s1,s2)->(s1+s2).compareTo(s2+s1));
且List接口也直接提供了sort方法
listStr.sort((s1,s2)->(s1+s2).compareTo(s2+s1));
方法四:
K神:本文列举 快速排序 和 内置函数 两种排序方法,其他排序方法也可实现。
作者:jyd
链接:https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/solution/mian-shi-ti-45-ba-shu-zu-pai-cheng-zui-xiao-de-s-4/
来源:力扣(LeetCode)
快速排序:
需修改快速排序函数中的排序判断规则。字符串大小(字典序)对比的实现方法:
Python/C++ 中可直接用 < , >;
Java 中使用函数 A.compareTo(B);
class Solution {
public String minNumber(int[] nums) {
String[] strs = new String[nums.length];
for(int i = 0; i < nums.length; i++)
strs[i] = String.valueOf(nums[i]);
quickSort(strs, 0, strs.length - 1);
StringBuilder res = new StringBuilder();
for(String s : strs)
res.append(s);
return res.toString();
}
void quickSort(String[] strs, int l, int r) {
if(l >= r) return;
int i = l, j = r;
String tmp = strs[i];
while(i < j) {
while((strs[j] + strs[l]).compareTo(strs[l] + strs[j]) >= 0 && i < j) j--;
while((strs[i] + strs[l]).compareTo(strs[l] + strs[i]) <= 0 && i < j) i++;
tmp = strs[i];
strs[i] = strs[j];
strs[j] = tmp;
}
strs[i] = strs[l];
strs[l] = tmp;
quickSort(strs, l, i - 1);
quickSort(strs, i + 1, r);
}
}
内置函数:
需定义排序规则:
Python 定义在函数 sort_rule(x, y) 中;
Java 定义为 (x, y) -> (x + y).compareTo(y + x) ;
C++ 定义为 (string& x, string& y){ return x + y < y + x; } ;
class Solution {
public String minNumber(int[] nums) {
String[] strs = new String[nums.length];
for(int i = 0; i < nums.length; i++)
strs[i] = String.valueOf(nums[i]);
Arrays.sort(strs, (x, y) -> (x + y).compareTo(y + x));
StringBuilder res = new StringBuilder();
for(String s : strs)
res.append(s);
return res.toString();
}
}
快排
From 脚丫先生
public class QuickSort {
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
//temp就是基准位
temp = arr[low];
while (i<j) {
//先看右边,依次往左递减
while (temp<=arr[j]&&i<j) {
j--;
}
//再看左边,依次往右递增
while (temp>=arr[i]&&i<j) {
i++;
}
//如果满足条件则交换
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
//最后将基准为与i和j相等位置的数字交换
arr[low] = arr[i];
arr[i] = temp;
//递归调用左半数组
quickSort(arr, low, j-1);
//递归调用右半数组
quickSort(arr, j+1, high);
}
public static void main(String[] args){
int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
总结
以上就是本题的内容和学习过程了,大概直观的思路自己也能想到,但是就是落实上,非科班知道的特性太少,有些想法脑子里有但是怎么用现有工具去实现就傻眼了,只能靠多积累。
欢迎讨论,共同进步。