剑指 Offer 45. 把数组排成最小的数
题目描述
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
输入: [3,30,34,5,9] 输出: "3033459"说明:
- 输出结果可能非常大,所以你需要返回一个字符串而不是整数
- 拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
思路
该题本质上是一个排序问题,设数组 numsnumsnums 中任意两数字的字符串为 xxx 和 yyy ,则规定排序判断规则如下:
- 若拼接字符串x+y > y+x ,则 x “大于” y ;
-
反之,若 x+y < y+x ,则 x “小于” y;
方法一:快速排序
根据上面的排序判断规则,应用快速排序进行实现
class Solution {
public String minNumber(int[] nums) {
int length = nums.length;
String[] strs = new String[length];
for(int i = 0; i < length; i++){ //将整数转换为字符串存入一个字符串数组
strs[i] = String.valueOf(nums[i]);
}
quickSort(strs, 0, length - 1);
StringBuilder sbr = new StringBuilder();
for(String str : strs){ //遍历拼接
sbr.append(str);
}
return sbr.toString();
}
public void quickSort(String[] strs, int start, int end){ //快速排序
if(start >= end){
return;
}
int left = start;
int right = end;
String pivot = strs[start]; //确定基准元素
while(left != right){
//拼接基准元素,比较并交换
while(left < right && (strs[right] + pivot).compareTo(pivot + strs[right]) >= 0){
right--;
}
while(left < right && (strs[left] + pivot).compareTo(pivot + strs[left]) <= 0){
left++;
}
if(left < right){
String temp = strs[left];
strs[left] = strs[right];
strs[right] = temp;
}
}
strs[start] = strs[left];
strs[left] = pivot;
int pivotIndex = left;
quickSort(strs, start, pivotIndex - 1); //对左边继续进行分治
quickSort(strs, pivotIndex + 1, end); //对右边继续进行分治
}
}
方法二:调用内置函数
调用内置函数,根据排序判断规则进行排序,
class Solution {
public String minNumber(int[] nums) {
int length = nums.length;
String[] strs = new String[length];
for(int i = 0; i < length; i++){ //将整数转换为字符串存入一个字符串数组
strs[i] = String.valueOf(nums[i]);
}
//调用内置函数,根据排序判断规则进行排序
Arrays.sort(strs, (x, y) -> (x + y).compareTo(y + x));
StringBuilder sbr = new StringBuilder();
for(String str : strs){ //遍历拼接
sbr.append(str);
}
return sbr.toString();
}
}
剑指 Offer 61. 扑克牌中的顺子
题目描述
从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
输入: [0,0,1,2,5] 输出: True 说明:大、小王为 0 ,可以看成任意数字,有两个0,2到5之间刚好缺少3,4,可使用0代替链接:https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof
思路
根据题意为顺子的规则:
- 除大小王外,所有牌无重复 ;
- 设此 5 张牌中最大的牌为 max,最小的牌为 min (大小王除外),则需满足:max-min < 5
代码实现
class Solution {
public boolean isStraight(int[] nums) {
int joker = 0; //大小王的数量
Arrays.sort(nums); //排序
for(int i = 0; i < 4; i++){
if(nums[i] == 0){ //为大小王就累加数量
joker++;
continue;
}
if(nums[i] == nums[i+1]){ //有重复直接返回false
return false;
}
}
//此时joker标识的是最小值,要求最大值-最小值小于5,才为顺子
return nums[4] - nums[joker] < 5;
}
}

京公网安备 11010502036488号