45.
题目:
剑指 Offer 45. 把数组排成最小的数https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/
想法:自定义排序.首先转换为字符串数组,然后通过快速排序排列字符串顺序.
参考:力扣k神
代码:
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();
}
//快排
private String[] quickSort(String[] strs, int low, int high) {
if (low < high) {
//使用基准,每一趟快排将low-high分成两段
int base = partition(strs, low, high);
quickSort(strs, low, base - 1);
quickSort(strs, base + 1, high);
}
return strs;
}
// 分区,返回大小分界线
public int partition(String[] strs, int low, int high) {
int base = low;
String baseValue = strs[low];
while (low < high) {
// 比较 递增
// 注意要先移动high后移动low
while(low < high &&(strs[high] + strs[base]).compareTo(strs[base] + strs[high]) >= 0)
high--;
while(low < high && (strs[low] + strs[base]).compareTo(strs[base] + strs[low]) <= 0)
low++;
// 上面的两个while也限制了low<high,所以不会有low>high
String tmp = strs[low];
strs[low] = strs[high];
strs[high] = tmp;
}
strs[base] = strs[low];
strs[low] = baseValue;
//返回新分界线
return low;
}
}
结果:
61.
题目:
剑指 Offer 61. 扑克牌中的顺子https://leetcode-cn.com/problems/bu-ke-pai-zhong-de-shun-zi-lcof/
想法:这题和扑克牌没啥关系,就是能不能组成顺子,以及0可以代替其他牌.
我写的:首先插入排序,其次统计牌的间隔gap数量和0的数量,再判断情况.
参考k神:只需判断最大牌与最小牌之间的间隔.最大是最后一个,最小的下标是joker数量.
代码:
//我:
class Solution {
public boolean isStraight(int[] nums) {
int pre,cur;
//插入排序
for(int i=1;i<nums.length;i++){
pre=i-1;
cur=nums[i];
while(pre>=0 && nums[pre]>cur){
nums[pre+1]=nums[pre];
pre--;
}
nums[pre+1]=cur;
}
//遍历
int zeros=0;
int gaps=0;
if(nums[0]==0)
zeros++;
for(int i=1;i<nums.length;i++){
if(nums[i]==0)
zeros++;
else if(nums[i]==nums[i-1])
return false;
else if(nums[i-1]!=0)
gaps=gaps+nums[i]-nums[i-1]-1;
}
if(gaps<=zeros||gaps==0)
return true;
else
return false;
}
}
//参考:
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++; // 统计大小王数量
else if(nums[i] == nums[i + 1]) return false; // 若有重复,提前返回 false
}
return nums[4] - nums[joker] < 5; // 最大牌 - 最小牌 < 5 则可构成顺子
}
}
结果: