leecode更新
This commit is contained in:
parent
32ebfcceb8
commit
467586e982
|
|
@ -29,13 +29,14 @@ public class FindMinArrowShots {
|
||||||
// System.out.println((long)(-2147483646)-(long)(2147483647)); //-4294967293
|
// System.out.println((long)(-2147483646)-(long)(2147483647)); //-4294967293
|
||||||
// System.out.println((int)((long)(-2147483646)-(long)(2147483647)));//3
|
// System.out.println((int)((long)(-2147483646)-(long)(2147483647)));//3
|
||||||
// System.out.println((int)(-2147483646)-(int)(2147483647)); //3
|
// System.out.println((int)(-2147483646)-(int)(2147483647)); //3
|
||||||
System.out.println(findMinArrowShots(points));
|
System.out.println(findMinArrowShots(points5));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 本人思路:先根据xstart进行排序,然后寻找第一个比xend大的xstart则result+1以此类推
|
* 本人思路:先根据xstart进行排序,然后寻找第一个比xend大的xstart则result+1以此类推
|
||||||
* 排序的时间复杂度为O(nlogn),所以总复杂度为O(nlogn)
|
* 排序的时间复杂度为O(nlogn),所以总复杂度为O(nlogn)
|
||||||
* 速度击败12.72%,内存击败88.71%
|
* 速度击败12.72%,内存击败88.71% =>修改compare方法后速度击败97.21%,内存击败91.4% 耗时52ms
|
||||||
|
* 代码随想录方法与本人一致
|
||||||
* @param points
|
* @param points
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
@ -46,7 +47,15 @@ public class FindMinArrowShots {
|
||||||
@Override
|
@Override
|
||||||
public int compare(int[] o1, int[] o2) {
|
public int compare(int[] o1, int[] o2) {
|
||||||
//警惕两数相减超过int范围
|
//警惕两数相减超过int范围
|
||||||
return o1[0] == o2[0] ? (o1[1] > o2[1]?1:-1) : (o1[0] > o2[0]?1:-1);
|
// return o1[0] == o2[0] ? (o1[1] > o2[1]?1:-1) : (o1[0] > o2[0]?1:-1);
|
||||||
|
//这里改为一层if速度超过97.21%
|
||||||
|
if(o1[0] > o2[0]){
|
||||||
|
return 1;
|
||||||
|
}else if(o1[0] < o2[0]){
|
||||||
|
return -1;
|
||||||
|
}else{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -70,4 +79,45 @@ public class FindMinArrowShots {
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方思路:先根据xend进行排序,然后寻找第一个比xend大的xstart则result+1以此类推
|
||||||
|
* 排序的时间复杂度为O(nlogn),所以总复杂度为O(nlogn)
|
||||||
|
* 速度击败30.68%,内存击败69.54% 59ms 这个应该有bug次次提交不一样,本质上应该比本人方法好,每次for都少判断一次
|
||||||
|
* @param points
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int findMinArrowShots1(int[][] points) {
|
||||||
|
|
||||||
|
//按xend进行排序
|
||||||
|
Arrays.sort(points, new Comparator<int[]>() {
|
||||||
|
@Override
|
||||||
|
public int compare(int[] o1, int[] o2) {
|
||||||
|
//这里两层if不太好,改为if写法,官方按xend进行排序
|
||||||
|
if (o1[1] > o2[1]) {
|
||||||
|
return 1;
|
||||||
|
} else if (o1[1] < o2[1]) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//遍历points,找到比xend大的xstart就+1
|
||||||
|
int result=1;
|
||||||
|
int lastEnd=points[0][1];
|
||||||
|
for (int i = 1; i < points.length; i++) {
|
||||||
|
if(points[i][0]>lastEnd){
|
||||||
|
result++;
|
||||||
|
lastEnd=points[i][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
package com.markilue.leecode.greedy;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: Leecode
|
||||||
|
* @BelongsPackage: com.markilue.leecode.greedy
|
||||||
|
* @Author: markilue
|
||||||
|
* @CreateTime: 2022-11-18 10:58
|
||||||
|
* @Description: TODO 力扣56题 合并区间:
|
||||||
|
* 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class Merge {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[][] points = {{1, 2}, {3, 4},{5, 6},{7, 8}};
|
||||||
|
int[][] points1 = {{1, 3}, {2, 6},{8, 10},{15, 18}};
|
||||||
|
int[][] points2 = {{1, 2}, {2, 3},{3, 4},{4, 5}};
|
||||||
|
int[][] points3 = {{1, 4}, {0, 4}};
|
||||||
|
int[][] points4 = {{-2147483646, -2147483645}, {2147483646, 2147483647}};
|
||||||
|
int[][] points5 = {{2,3}, {2, 2},{3, 3},{1, 3}, {5, 7}, {2, 2},{4, 6}};
|
||||||
|
// System.out.println((long)(-2147483646)-(long)(2147483647)); //-4294967293
|
||||||
|
// System.out.println((int)((long)(-2147483646)-(long)(2147483647)));//3
|
||||||
|
// System.out.println((int)(-2147483646)-(int)(2147483647)); //3
|
||||||
|
int[][] merge = merge(points2);
|
||||||
|
for (int[] ints : merge) {
|
||||||
|
System.out.println(Arrays.toString(ints));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本人思路:与射箭那题类似,本质上是找到重叠区间,因此仍然是按xstart排序,然后再一次循环寻找重叠区间
|
||||||
|
* 速度击败71.63%,内存击败90.55% 7ms =>compare优化以后 速度击败97.55%,内存击败53.75%
|
||||||
|
* @param intervals
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int[][] merge(int[][] intervals) {
|
||||||
|
|
||||||
|
//按xstart排序
|
||||||
|
Arrays.sort(intervals, new Comparator<int[]>() {
|
||||||
|
@Override
|
||||||
|
public int compare(int[] o1, int[] o2) {
|
||||||
|
// if(o1[0]>o2[0]){
|
||||||
|
// return 1;
|
||||||
|
// } else if (o1[0]<o2[0]) {
|
||||||
|
// return -1;
|
||||||
|
// }else {
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
//优化
|
||||||
|
return o1[0] - o2[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//寻找重叠区间,并进行合并
|
||||||
|
int length=0;//记录新数组的长度
|
||||||
|
int[][] result =new int[intervals.length][2];
|
||||||
|
result[0]=intervals[0];
|
||||||
|
int lastEnd=intervals[0][1];
|
||||||
|
|
||||||
|
for (int i = 1; i < intervals.length; i++) {
|
||||||
|
if(lastEnd>=intervals[i][0]){
|
||||||
|
//重叠区间,需要合并
|
||||||
|
lastEnd=Math.max(lastEnd,intervals[i][1]);
|
||||||
|
result[length][1]=lastEnd;
|
||||||
|
}else {
|
||||||
|
//非重叠区间,直接添加
|
||||||
|
length++;
|
||||||
|
result[length]=intervals[i];
|
||||||
|
lastEnd=intervals[i][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//缩短至result的真实长度
|
||||||
|
return Arrays.copyOf(result,length+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方代码:与本人类似,并使用动态扩容的arrayList记录添加
|
||||||
|
* 速度击败97.55%,内存击败9.14%
|
||||||
|
* @param intervals
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int[][] merge1(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 L = intervals[i][0], R = intervals[i][1];
|
||||||
|
if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) {
|
||||||
|
merged.add(new int[]{L, R});
|
||||||
|
} else {
|
||||||
|
merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return merged.toArray(new int[merged.size()][]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,137 @@
|
||||||
|
package com.markilue.leecode.greedy;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @BelongsProject: Leecode
|
||||||
|
* @BelongsPackage: com.markilue.leecode.greedy
|
||||||
|
* @Author: markilue
|
||||||
|
* @CreateTime: 2022-11-18 11:44
|
||||||
|
* @Description: TODO 力扣738题 单调递增的数字:
|
||||||
|
* 当且仅当每个相邻位数上的数字 x 和 y 满足 x <= y 时,我们称这个整数是单调递增的。
|
||||||
|
* 给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。
|
||||||
|
* @Version: 1.0
|
||||||
|
*/
|
||||||
|
public class MonotoneIncreasingDigits {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int n = 1234;
|
||||||
|
int n1 = 10;
|
||||||
|
int n2 = 332;
|
||||||
|
int n3=15;
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println(monotoneIncreasingDigits2(n2));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 本人思路:可以发现的是,如果一个数最高位小于其后一位,那么无论如何都是需要把最高位减1的,而这时后面的数就可以随便取9了;后续位依次类推,直至/10=0为止
|
||||||
|
* 这里有个矛盾的点是我们需要从最高位开始判,但是事实上我们不知道数字具体有多少位,只能不断/10来判 =>因此可以把n转为string获取长度
|
||||||
|
*
|
||||||
|
* 速度击败94.57%,内存击败33.72%
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int monotoneIncreasingDigits(int n) {
|
||||||
|
|
||||||
|
String s = n + "";
|
||||||
|
int length = s.length();
|
||||||
|
if (length == 1) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] num = new int[length];
|
||||||
|
num[0]=n%10;
|
||||||
|
int index=1;
|
||||||
|
|
||||||
|
n=n/10;
|
||||||
|
//这里仍然使用从后往前遍历,因为如果从前往后,后续又出现借的情况前面的逻辑可能有需要重新判一次
|
||||||
|
while (n>0&&n/10>=0){
|
||||||
|
|
||||||
|
int now = n%10;
|
||||||
|
if(now>num[index-1]){
|
||||||
|
now=now-1;
|
||||||
|
//当前减1后面全9
|
||||||
|
num[index]=now;
|
||||||
|
for (int i = 0; i <= index - 1; i++) {
|
||||||
|
num[i]=9;
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
num[index]=now;
|
||||||
|
}
|
||||||
|
n=n/10;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
int result=0;
|
||||||
|
for (int i = length-1; i >= 0; i--) {
|
||||||
|
result*=10;
|
||||||
|
result+=num[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方题解:从前往后遍历,找到不合题解的位置,则把前面的数-1,后面的数全部置为9
|
||||||
|
* 这种其实是比本人的优化的,因为本人是从后往前遍历,因此置为9的循环操作可能会持续很多次
|
||||||
|
* 速度击败94.57%,内存击败57.77%
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int monotoneIncreasingDigits1(int n) {
|
||||||
|
char[] strN = Integer.toString(n).toCharArray();
|
||||||
|
int i = 1;
|
||||||
|
while (i < strN.length && strN[i - 1] <= strN[i]) {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
if (i < strN.length) {
|
||||||
|
//找到不合适的位置,一次性全部完成,所以最多只需要执行一次置为9循环
|
||||||
|
while (i > 0 && strN[i - 1] > strN[i]) {
|
||||||
|
strN[i - 1] -= 1;
|
||||||
|
i -= 1;
|
||||||
|
}
|
||||||
|
for (i += 1; i < strN.length; ++i) {
|
||||||
|
strN[i] = '9';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Integer.parseInt(new String(strN));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 评论里的题解:整体思路和官方差不多,但是他用n - Integer.parseInt(s.substring(1)) - 1;这种操作,避免了for循环,速度增加
|
||||||
|
* 速度击败100%,内部击败79.4%,
|
||||||
|
*
|
||||||
|
* @param n
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int monotoneIncreasingDigits2(int n) {
|
||||||
|
if (n < 10){
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
String s = Integer.toString(n);
|
||||||
|
for (int i = 1; i < s.length(); i++) {
|
||||||
|
if (s.charAt(i) < s.charAt(i - 1)){
|
||||||
|
int temp = i - 1;
|
||||||
|
while (true){
|
||||||
|
if (temp == 0){
|
||||||
|
return n - Integer.parseInt(s.substring(1)) - 1; //整体需要少一位,所以n-他后面的数-1如1056-056-1=999
|
||||||
|
}else if (s.charAt(temp) - s.charAt(temp - 1) >= 1){ //当前数与前面的数之差大于1,则放心的把当前数减1
|
||||||
|
return n - Integer.parseInt(s.substring(temp + 1)) - 1;//如1306-06-1=1299
|
||||||
|
}
|
||||||
|
temp--;//如果相差小于1了,则不能直接减,因此从上一个点来看看
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue