1)方法一:将当前遍历的字符x与下一个字符y拼接相加起来的值x+y与y+x的大小进行一轮次比较,>0则不断交换当前位与下一位,进行n轮次比较【O(n^2)】
-
- /**
- * 输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
- * 输入: [3,30,34,5,9]
- * 输出: "3033459"
- **/
-
- public class 把数组排成最小的数 {
- /**
- * 比较当前遍历的字符x与下一个字符y拼接相加起来的值x+y与y+x的大小,x+y字符串对应小于y+x的话就不用交换位置,否则交换位置
- * 这里的字符串比较用到compareTo
- * @param nums
- * @return
- */
- public String minNumber(int[] nums) {
- //先将nums数组转为字符串数组
- String[] str=new String[nums.length];
- for (int i = 0; i < str.length; i++) {
- str[i]=String.valueOf(nums[i]);
- }
- for (int i = 0; i < str.length; i++) {
- for (int j = 0; j < str.length - 1; j++) {
- if((str[j]+str[j+1]).compareTo(str[j+1]+str[j])>0){//x+y>y+x// 比如 34,3 --> 343 > 334 所以两个数需要交换位置
- String s=str[j];
- str[j]=str[j+1];
- str[j+1]=s;
- }
- }
- }
- //交换完毕字符串数组中就是需要的数组顺序结果,将他转为字符串
- StringBuilder sb=new StringBuilder();
- for (int i = 0; i < str.length; i++) {
- sb.append(str[i]);
- }
- return sb.toString();
- }
- }
2)方法2:应用快排思想思考:
数据结构之七大排序3—快速排序详解_林纾໌້ᮨ的博客-CSDN博客_数据结构快速排序
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);
}
}


- /**
- * 从若干副扑克牌中随机抽 5 张牌,判断是不是一个顺子,即这5张牌是不是连续的。
- * 2~10为数字本身,A为1,J为11,Q为12,K为13,而大、小王为 0 ,可以看成任意数字。A 不能视为 14。
- * 输入: [1,2,3,4,5]
- * 输出: True
- * 输入: [0,0,1,2,5]
- * 输出: True
- **/
- //除大小王外无重复的牌(数字),且最大值-最小值<5时可连成顺子。注意最小值不包括大小王对应的0值
- public class Num61_扑克牌中的顺子 {
- /**
- * 方法一:集合Set+遍历
- * 遍历五张牌,遇到大小王(即0)直接跳过。
- * 判别重复:利用Set实现遍历判重,Set的查找方法的时间复杂度为 O(1);
- * 获取最大/最小的牌:借助辅助变量ma和mi,遍历统计即可。
- * 当最大牌-最小牌=max-min<5就可以构成顺子
- * @param nums
- * @return
- */
- public boolean isStraight(int[] nums) {
- Set
set=new HashSet<>(); - int max=0;
- int min=14;
- for(int num:nums){
- if(num==0){
- //遇到大小王(0:可以代替任何牌)直接跳过
- continue;
- }
- max=Math.max(max,num);
- min=Math.min(min,num);
- //若有重复牌,直接返回false
- if(set.contains(num)){
- return false;
- }
- set.add(num);//此时没有重复牌,将其放入set集合中
- }
- // if(max-min<5){
- // return true;
- // }else {
- // return false;
- // }
- return max-min<5;
- }
- /**
- * 方法二:排序+遍历
- * 先对数组执行排序。
- * 判别重复:排序数组中的相同元素位置相邻,因此可通过遍历数组,判断nums[i]=nums[i+1]是否成立来判重。
- * 获取最大/最小的牌:排序后,数组末位元素nums[4]为最大牌;元素nums[joker]为最小牌,其中joker为大小王的数量。
- */
- public boolean isStraight2(int[] nums) {
- int joker=0;//统计大小王的数量
- Arrays.sort(nums);//数组排序
- //排序后重复元素一定相邻,如没有重复元素,max-min<5即顺子【大小王(0)可以代表任何数字,遇到0跳过】
- //max一定是num[4],min一定是num[joker](因为0不算在min中)
- for (int i = 0; i < 4; i++) {
- if(nums[i]==0){
- joker++;//统计大小王数量
- }else if(nums[i]==nums[i+1]){
- return false;//遇到重复,提前返回false
- }
- }
- return nums[4]-nums[joker]<5;
- }
- }