所有的题集:5.LeetCode刷题记录[排序]排序部分题目_foolish的博客-CSDN博客
关键点:对数组中的数字以字符串的形式进行组合排序,例如[x,y,z] (y+x).compareTo(x+y);根据要求看x在前还是y在前。这道题是y+x这样的形式,形成升序排序。通过两个数字的字符串进行组合排序,可以得到最大值。
class Solution {
public String largestNumber(int[] nums) {
Queue<String> pq = new PriorityQueue<String>((x,y)->(x+y).compareTo(y+x));
for (int i : nums) {
pq.offer(String.valueOf(i));
}
String res = "";
while(pq.size()>0){
res += pq.poll();
}
if(res.charAt(0) == '0') return "0";//特殊情况
return res;
}
剑指 Offer 45. 把数组排成最小的数(类似)
class Solution {
public String minNumber(int[] nums) {
// Queue<String> queue = PriorityQueue<String>((x,y)->(x+y).compareTo(y+x));
Queue<String> queue = new PriorityQueue<String>((x,y)->(x+y).compareTo(y+x));
for(int i:nums){
queue.offer(String.valueOf(i));
}
String res = "";
while(queue.size()>0){
res += queue.poll();
}
// if(res.charAt(0)=='0') return "0";
return res;
}
}
349. 两个数组的交集(这道题感觉是用Set方便一些)前面已经做过了 就不在这提了
75. 颜色分类(所有的排序方法都能通过过一遍,类似于912)
56. 合并区间https://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/merge-intervals/
class Solution {
public int[][] merge(int[][] intervals) {
if (intervals.length == 0) {
return new int[0][2];
}
Arrays.sort(intervals,new Comparator<int[]>(){
public int compare(int[] interval1,int[] interval2){
return interval1[0] - interval2[0];
}
});
List<int[]> merged = new ArrayList<int[]>();
for (int i = 0; i < intervals.length; i++) {
int left = intervals[i][0];
int right = intervals[i][1];
//a[i].end<a[j].start(a[i] 和 a[j] 不能合并)
//a[j].end<a[k].start(a[j] 和 a[k] 不能合并)
//a[i].end≥a[k].start(a[i] 和 a[k] 可以合并)
if(merged.size()==0||merged.get(merged.size()-1)[1]<left){
merged.add(new int[]{left,right});
}else{
merged.get(merged.size()-1)[1] = Math.max(merged.get(merged.size()-1)[1],right);
}
}
return merged.toArray(new int[merged.size()][]);
}
}
253. 会议室 IIhttps://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/meeting-rooms-ii(这是一道VIP题 网上能搜到)
给定一个会议时间安排的数组,每个会议时间都会包括开始和结束的时间 [[s1,e1],[s2,e2],…] (si < ei),为避免会议冲突,同时要考虑充分利用会议室资源,请你计算至少需要多少间会议室,才能满足这些会议安排。
示例 1:
输入: [[0, 30],[5, 10],[15, 20]]
输出:
输入: [[7,10],[2,4]]
输出: 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/meeting-rooms-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
import java.util.LinkedList;
class Solution {
public int minMeetingRooms(int[][] intervals) {
if(intervals == null || intervals.length == 0){
return 0;
}
Arrays.sort(intervals,(o1,o2)->o1[0]-o2[0]);
PriorityQueue<Integer> queue = new PriorityQueue<>((o1,o2)->o1-o2);
queue.offer(intervals[0][1]);
for(int i = 1;i < intervals.length;i++){
if(intervals[i][0]>=queue.peek()){
queue.poll();
}
queue.offer(intervals[i][1]);
}
return queue.size();
}
}
56. 合并区间https://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/merge-intervals/(和上一题有异曲同工之处)
class Solution {
public int[][] merge(int[][] intervals) {
if (intervals.length == 0) {
return new int[0][2];
}
Arrays.sort(intervals,new Comparator<int[]>(){
public int compare(int[] interval1,int[] interval2){
return interval1[0] - interval2[0];
}
});
List<int[]> merged = new ArrayList<int[]>();
for (int i = 0; i < intervals.length; i++) {
int left = intervals[i][0];
int right = intervals[i][1];
//a[i].end<a[j].start(a[i] 和 a[j] 不能合并)
//a[j].end<a[k].start(a[j] 和 a[k] 不能合并)
//a[i].end≥a[k].start(a[i] 和 a[k] 可以合并)
if(merged.size()==0||merged.get(merged.size()-1)[1]<left){
merged.add(new int[]{left,right});
}else{
merged.get(merged.size()-1)[1] = Math.max(merged.get(merged.size()-1)[1],right);
}
}
return merged.toArray(new int[merged.size()][]);
}
}
总结:253是统计数量,用优先队列很方便,因为他不需要管区间的开始,56题返回的是区间,他需要考虑区间的开始。
class Solution {
public int maxEvents(int[][] events) {
//首先排序:开始时间小的在前。这样是方便我们顺序遍历,把开始时间一样的都放进堆
Arrays.sort(events, (o1, o2) -> o1[0] - o2[0]);
//小顶堆
PriorityQueue<Integer> pq = new PriorityQueue<>();
//结果、开始时间、events下标、有多少组数据
int res = 0, index = 1, i = 0, n = events.length;
while (i < n || !pq.isEmpty()) {
//将start相同的会议都放进堆里
while (i < n && events[i][0] == index ) {
pq.offer(events[i++][1]);
}
//pop掉当前天数之前的
while (!pq.isEmpty() && pq.peek() < index ) {
pq.poll();
}
//统计参与的会议数
if (!pq.isEmpty()) {
pq.poll();
res++;
}
last++;
}
return res;
}
}
剑指 Offer 51. 数组中的逆序对
官方解答:数组中的逆序对 - 数组中的逆序对 - 力扣(LeetCode) (leetcode-cn.com)
315. 计算右侧小于当前元素的个数(做这道题得先看看前面这道题)
官方题解:计算右侧小于当前元素的个数 - 计算右侧小于当前元素的个数 - 力扣(LeetCode) (leetcode-cn.com)
总结:两道题得难度在于处理大数组得情况,意思就是时间复杂度得问题。
767. 重构字符串https://link.zhihu.com/?target=https%3A//leetcode-cn.com/problems/reorganize-string/(感觉我的解决思路跟排序无关)
class Solution {
public String reorganizeString(String s) {
char[] sChar = s.toCharArray();
int[] sCharCount = new int[26];
for (int i = 0; i < sChar.length; i++) {
sCharCount[sChar[i]-'a'] += 1;
}
//判断最大重复的字母是不是大于一字符长度的一般
//多写几组例子可以发现+1/2之后 会有一个不能重新排布的阈值
int threshold = (s.length()+1)/2;
int temp = 0;;
int max = 0;
for (int i = 0; i < sCharCount.length; i++) {
if (sCharCount[i] > max) {
max = sCharCount[i];
temp = i;
//如果出现次数最多的那个字符的数量大于阈值,说明他不能使得
// 两相邻的字符不同,直接返回空字符串即可
if (max > threshold)
return "";
}
}
//后面就随意排布就行
//偶数序号先放字母数多的
int index = 0;
char[] res = new char[s.length()];
while(sCharCount[temp]-->0){
res[index] = (char)('a'+temp);
index += 2;
}
//其余的字母也是间隔放
for (int i = 0; i < sCharCount.length; i++) {
while(sCharCount[i]-->0){
if(index>=res.length){
index = 1;
}
res[index] = (char)(i+'a');//先将偶数填满
index += 2;
}
}
return new String(res);
}
}