leecode更新

This commit is contained in:
markilue 2023-04-22 13:50:32 +08:00
parent 87cd1739e4
commit 03bc9f9c6b
14 changed files with 836 additions and 30 deletions

View File

@ -0,0 +1,57 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-04-20 11:28
*@Description:
* TODO 力扣4题 寻找两个正序数组的中位数:
* 给定两个大小分别为 m n 的正序从小到大数组 nums1 nums2请你找出并返回这两个正序数组的 中位数
* 算法的时间复杂度应该为 O(log (m+n))
*@Version: 1.0
*/
public class T04_4_FindMedianSortedArrays {
@Test
public void test(){
int[] nums1={1,3};
int[] nums2={2};
System.out.println(findMedianSortedArrays(nums1,nums2));
}
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n = nums1.length;
int m = nums2.length;
int left = (n + m + 1) / 2;
int right = (n + m + 2) / 2;
////将偶数和奇数的情况合并如果是奇数会求两次同样的 k
//比如n=5,m=5,则left=5,right=6; 合理
//比如n=5,m=6,则left=6,right=6; 合理
return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;
}
private int getKth(int[] nums1, int start1, int end1, int[] nums2, int start2, int end2, int k) {
int len1 = end1 - start1 + 1;
int len2 = end2 - start2 + 1;
//保证如果数组空了就一定是len1
if (len1 > len2) return getKth(nums2, start2, end2, nums1, start1, end1, k);
if (len1 == 0) return nums2[start2 + k - 1];
if (k == 1) return Math.min(nums1[start1], nums2[start2]);
//会直接比较k/2的位置
int i = start1 + Math.min(len1, k / 2) - 1;
int j = start2 + Math.min(len2, k / 2) - 1;
if (nums1[i] > nums2[j]) {
return getKth(nums1, start1, end1, nums2, j + 1, end2, k - (j - start2 + 1));//j-start2+1就抛弃的长度
} else {
return getKth(nums1, i + 1, end1, nums2, start2, end2, k - (i - start1 + 1));//i - start1 + 1就是抛弃的长度
}
}
}

View File

@ -0,0 +1,59 @@
package com.markilue.leecode.hot100.second;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-04-20 11:57
*@Description:
* TODO 力扣10 正则表达式匹配:
* 给你一个字符串 s 和一个字符规律 p请你来实现一个支持 '.' '*' 的正则表达式匹配
* '.' 匹配任意单个字符
* '*' 匹配零个或多个前面的那一个元素
* 所谓匹配是要涵盖 整个 字符串 s的而不是部分字符串
*@Version: 1.0
*/
public class T10_10_IsMatch {
/**
* 动态规划法:dp[i][j]表示使用s[0-i]和p[0-j]能否匹配上
* @param s
* @param p
* @return
*/
public boolean isMatch(String s, String p) {
int m = s.length();
int n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[0][0] = true;
for (int i = 0; i < dp.length; i++) {
for (int j = 1; j < dp[0].length; j++) {
if (p.charAt(j - 1) == '*') {
dp[i][j] = dp[i][j - 2];//不匹配字符将该组合扔掉不再进行匹配
if (matches(s, p, i, j - 1)) {
//如果当前值还和上一个一样
dp[i][j] |= dp[i - 1][j];////能匹配 s 末尾的一个字符将该字符扔掉而该组合还可以继续进行匹配
}
} else {
if (matches(s, p, i, j)) {
dp[i][j] = dp[i - 1][j - 1];
}
}
}
}
return dp[m][n];
}
public boolean matches(String s, String p, int i, int j) {
if (i == 0) return false;
if (p.charAt(j - 1) == '.') {
return true;
}
return s.charAt(i - 1) == p.charAt(j - 1);
}
}

View File

@ -0,0 +1,56 @@
package com.markilue.leecode.hot100.second;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-04-22 11:10
*@Description:
* TODO 力扣15 三数之和:
* 给你一个整数数组 nums 判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != ji != k j != k 同时还满足 nums[i] + nums[j] + nums[k] == 0
* 你返回所有和为 0 且不重复的三元组
* 注意答案中不可以包含重复的三元组
*@Version: 1.0
*/
public class T11_15_ThreeSum {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> result = new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
if (nums[i] > 0) break;
if (i != 0 && nums[i] == nums[i - 1]) {
continue;
}
int left = i + 1;
int right = nums.length - 1;
while (left < right) {
long sum = nums[left] + nums[right];
if (-nums[i] < sum) {
//>0
right--;
} else if (-nums[i] > sum) {
left++;
} else {
//刚好符合
result.add(new ArrayList<>(Arrays.asList(nums[i], nums[left], nums[right])));
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
}
}
}
return result;
}
}

View File

@ -0,0 +1,57 @@
package com.markilue.leecode.hot100.second;
import org.omg.CORBA.PUBLIC_MEMBER;
import java.sql.Array;
import java.util.*;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-04-22 11:32
*@Description:
* TODO 力扣17 电话号码的字母组合:
* 给定一个仅包含数字 2-9 的字符串返回所有它能表示的字母组合答案可以按 任意顺序 返回
* 给出数字到字母的映射如下与电话按键相同注意 1 不对应任何字母
*@Version: 1.0
*/
public class T12_17_LetterCombinations {
Map<Character, List<Character>> map = new HashMap() {{
put('2', Arrays.asList('a', 'b', 'c'));
put('3', Arrays.asList('d', 'e', 'f'));
put('4', Arrays.asList('g', 'h', 'i'));
put('5', Arrays.asList('j', 'k', 'l'));
put('6', Arrays.asList('m', 'n', 'o'));
put('7', Arrays.asList('p', 'q', 'r', 's'));
put('8', Arrays.asList('t', 'u', 'v'));
put('9', Arrays.asList('w', 'x', 'y', 'z'));
}};
List<String> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
public List<String> letterCombinations(String digits) {
if (digits.length() == 0) return result;
backtracking(digits.toCharArray(), 0);
return result;
}
public void backtracking(char[] chars, int startIndex) {
if (startIndex == chars.length) {
result.add(sb.toString());
return;
}
List<Character> list = map.get(chars[startIndex]);
for (Character character : list) {
sb.append(character);
backtracking(chars, startIndex + 1);
sb.deleteCharAt(sb.length() - 1);
}
}
}

View File

@ -0,0 +1,41 @@
package com.markilue.leecode.hot100.second;
import com.markilue.leecode.listnode.ListNode;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-04-22 11:42
*@Description:
* TODO 力扣19 删除链表的倒数第N个节点:
* 给你一个链表删除链表的倒数第 n 个结点并且返回链表的头结点
*@Version: 1.0
*/
public class T13_19_RemoveNthFromEnd {
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode fake = new ListNode();
fake.next = head;
ListNode fast = fake;
ListNode slow = fake;
while (fast != null && n-- > 0) {
fast = fast.next;
}
if (fast == null) {
//不够
return head;
}
while (fast.next != null) {
//走到头
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return fake.next;
}
}

View File

@ -0,0 +1,44 @@
package com.markilue.leecode.hot100.second;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-04-22 11:50
*@Description:
* TODO 力扣20 有效的括号:
* 给定一个只包括 '('')''{''}''['']' 的字符串 s 判断字符串是否有效
* 有效字符串需满足
* 左括号必须用相同类型的右括号闭合
* 左括号必须以正确的顺序闭合
* 每个右括号都有一个对应的相同类型的左括号
*@Version: 1.0
*/
public class T14_20_IsValid {
public boolean isValid(String s) {
HashMap<Character, Character> map = new HashMap() {{
put('(', ')');
put('[', ']');
put('{', '}');
}};
Deque<Character> stack = new ArrayDeque<>();
for (char c : s.toCharArray()) {
if (map.containsKey(c)) {
stack.push(map.get(c));
} else {
if (stack.isEmpty() || c != stack.peek()) return false;
stack.pop();
}
}
return stack.size()==0;
}
}

View File

@ -0,0 +1,41 @@
package com.markilue.leecode.hot100.second;
import com.markilue.leecode.listnode.ListNode;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-04-22 11:59
*@Description:
* TODO 力扣21 合并两个有序链表:
* 将两个升序链表合并为一个新的 升序 链表并返回新链表是通过拼接给定的两个链表的所有节点组成的
*@Version: 1.0
*/
public class T15_21_MergeTwoLists {
/**
*
* @param list1
* @param list2
* @return
*/
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null) {
return list2;
} else if (list2 == null) {
return list1;
}
ListNode root = new ListNode();
if (list1.val < list2.val) {
root.val = list1.val;
root.next = mergeTwoLists(list1.next, list2);
} else {
root.val = list2.val;
root.next = mergeTwoLists(list1, list2.next);
}
return root;
}
}

View File

@ -0,0 +1,55 @@
package com.markilue.leecode.hot100.second;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100.second
*@Author: markilue
*@CreateTime: 2023-04-22 12:09
*@Description:
* TODO 力扣22 括号生成:
* 数字 n 代表生成括号的对数请你设计一个函数用于能够生成所有可能的并且 有效的 括号组合
*@Version: 1.0
*/
public class T16_22_GenerateParenthesis {
@Test
public void test() {
System.out.println(generateParenthesis(3));
}
List<String> result = new ArrayList<>();
StringBuilder sb = new StringBuilder();
public List<String> generateParenthesis(int n) {
backtracking(n, 0, 0);
return result;
}
public void backtracking(int n, int left, int right) {
if (left > n || right > n || right > left) return;
if (left == n && right == n) {
result.add(sb.toString());
return;
}
if (left < n) {
sb.append('(');
backtracking(n, left + 1, right);
sb.deleteCharAt(sb.length() - 1);
}
if (right < n) {
sb.append(')');
backtracking(n, left, right + 1);
sb.deleteCharAt(sb.length() - 1);
}
}
}

View File

@ -0,0 +1,69 @@
package com.markilue.leecode.interview.meituan;
import com.markilue.leecode.listnode.ListNode;
import com.markilue.leecode.listnode.ListNodeUtils;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.interview.meituan
*@Author: markilue
*@CreateTime: 2023-04-21 11:12
*@Description:
* TODO 力扣25 K 个一组翻转链表:
* 给你链表的头节点 head k 个节点一组进行翻转请你返回修改后的链表
* k 是一个正整数它的值小于或等于链表的长度如果节点总数不是 k 的整数倍那么请将最后剩余的节点保持原有顺序
* 你不能只是单纯的改变节点内部的值而是需要实际进行节点交换
*@Version: 1.0
*/
public class LC_25_ReverseKGroup {
@Test
public void test(){
ListNode root = ListNodeUtils.build(new int[]{1, 2, 3, 4, 5});
ListNodeUtils.print(reverseKGroup(root,2));
}
public ListNode reverseKGroup(ListNode head, int k) {
if (head == null) {
return head;
}
ListNode temp = head;
for (int i = 0; i < k; i++) {
if (temp == null) return head;//不足k个
temp = temp.next;
}
ListNode newHead = reverse(head, temp);
head.next = reverseKGroup(temp, k);
return newHead;
}
/**
* 反转从head到end
* @param head
* @param end
* @return
*/
public ListNode reverse(ListNode head, ListNode end) {
if(head==null) return head;
ListNode fake = new ListNode();
ListNode temp = head;
ListNode temp1;
while (temp != end) {
temp1 = temp.next;
temp.next = fake.next;
fake.next = temp;
temp = temp1;
}
return fake.next;
}
}

View File

@ -0,0 +1,64 @@
package com.markilue.leecode.interview.meituan;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.interview.meituan
*@Author: markilue
*@CreateTime: 2023-04-21 11:41
*@Description: TODO 力扣45 跳跃游戏II:
*@Version: 1.0
*/
public class LC_45_Jump {
@Test
public void test(){
int[] nums={2,3,1,1,4};
System.out.println(jump1(nums));
}
public int jump(int[] nums) {
if (nums.length == 1) {
return 0;
}
int maxGet = nums[0];
int lastGet = nums[0];
int cur = 1;
for (int i = 1; i < nums.length - 1; i++) {
if (lastGet < i) {
cur++;
lastGet = maxGet;
}
maxGet = Math.max(maxGet, nums[i] + i);
if (maxGet >= nums.length - 1) return cur + 1;
}
return maxGet > nums.length - 1 ? cur : 0;
}
public int jump1(int[] nums) {
if (nums.length == 1) {
return 0;
}
int maxGet = -1;
int lastGet = -1;
int cur = 0;
for (int i = 0; i < nums.length - 1; i++) {
if (lastGet < i) {
cur++;
lastGet = maxGet;
}
maxGet = Math.max(maxGet, nums[i] + i);
if (maxGet >= nums.length - 1) return cur ;
}
return maxGet >= nums.length - 1 ? cur : 0;
}
}

View File

@ -0,0 +1,164 @@
package com.markilue.leecode.interview.meituan;
import org.junit.Test;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.util.ArrayDeque;
import java.util.Deque;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.interview.meituan
*@Author: markilue
*@CreateTime: 2023-04-21 10:15
*@Description: TODO 力扣71 简化路径
*@Version: 1.0
*/
public class LC_71_SimplifyPath {
public static void main(String[] args) throws IOException {
// StreamTokenizer re = new StreamTokenizer(System.in);
// re.nextToken();
// int int1 = (int)re.nval;
// System.out.println(int1);
for (int i = 0; i < 5; i++) {
new Thread(new Runnable(){
public void run(){
System.out.println(Thread.currentThread().getName());
}
},"thread"+i).start();
}
}
@Test
public void test() {
String path = "/a/./b/../../c/";
System.out.println(simplifyPath1(path));
}
@Test
public void test1() {
String path = "/home//foo/";
System.out.println(simplifyPath2(path));
}
@Test
public void test2() {
String path = "/.";
System.out.println(simplifyPath(path));
}
@Test
public void test3() {
String path = "/abc";
System.out.println(simplifyPath(path));
}
public String simplifyPath(String path) {
StringBuilder sb = new StringBuilder();
char[] chars = path.toCharArray();
if (chars[0] == '/') {
sb.append('/');
}
for (int i = 1; i < chars.length; i++) {
if (Character.isLetterOrDigit(chars[i])) {
while (i < chars.length && (Character.isLetterOrDigit(chars[i]) || chars[i] == '_')) {
sb.append(chars[i]);
i++;
}
i--;//不是之后回退一步
} else if (chars[i] == '.') {
if (i + 1 < chars.length && chars[i + 1] == '.') {
for (int j = 0; j < 2; j++) {
if (sb.length() == 0) {
continue;
}
int index = sb.lastIndexOf("/");
sb.delete(index, sb.length());
}
i++;
}
} else if (chars[i] == '/') {
if (sb.length() == 0 || sb.charAt(sb.length() - 1) != '/') {
sb.append(chars[i]);
}
}
}
if (sb.length() == 0) {
sb.append('/');
}
if (sb.length() > 1 && sb.charAt(sb.length() - 1) == '/') {
sb.deleteCharAt(sb.length() - 1);
}
return sb.toString();
}
/**
* 官方题解:使用一个栈记录
* 速度击败49.47% 内存击败43.46% 4ms
* @param path
* @return
*/
public String simplifyPath1(String path) {
String[] name = path.split("/");
Deque<String> stack = new ArrayDeque<>();
for (String s : name) {
if ("..".equals(s)) {
if (!stack.isEmpty()) {
stack.pollLast();
}
} else if (s.length() > 0 && !".".equals(s)) {
stack.offerLast(s);
}
}
StringBuilder sb = new StringBuilder();
if (stack.isEmpty()) {
sb.append("/");
} else {
while (!stack.isEmpty()) {
sb.append("/");
sb.append(stack.pollFirst());
}
}
return sb.toString();
}
//优秀解法:不用split,挨个找也可以直接避免split之后有的为""的情况;速度击败98.98% 内存击败21.42%
public String simplifyPath2(String path) {
Deque<String> deque = new ArrayDeque<>();
int n = path.length();
for (int i = 1; i < n; i++) {
if (path.charAt(i) == '/') continue; // 找到下一个不是"/"的位置
int j = i + 1; // j指向下一个位置双指针
while (j < n && path.charAt(j) != '/') j++; // 直到j指向的位置是"/"
String temp = path.substring(i, j); // 左闭右开[i.j)
if (temp.equals("..")) { //..的时候栈内有元素才删
if (!deque.isEmpty()) {
deque.pollLast();
}
} else if (!(temp.equals("."))) { // .的时候就continue这里省略了不是.的时候就进栈
deque.addLast(temp);
}
i = j; //j是指向"/"令i=j开始下一轮循环
}
StringBuilder ans = new StringBuilder();
while (!deque.isEmpty()) { // 还原栈内的路径
ans.append("/");
ans.append(deque.pollFirst());
}
return ans.length() == 0 ? "/" : ans.toString(); // 栈为空就直接返回"/",否则返回ans.toString()
}
}

View File

@ -1,6 +1,8 @@
package com.markilue.leecode.listnode.selftry; package com.markilue.leecode.listnode.selftry;
import com.markilue.leecode.listnode.ListNode; import com.markilue.leecode.listnode.ListNode;
import com.markilue.leecode.listnode.ListNodeUtils;
import org.junit.Test;
/** /**
*@BelongsProject: Leecode *@BelongsProject: Leecode
@ -18,6 +20,13 @@ import com.markilue.leecode.listnode.ListNode;
*/ */
public class ReorderList { public class ReorderList {
@Test
public void test() {
ListNode root = ListNodeUtils.build(new int[]{1, 2, 3, 4, 5});
reorderList(root);
ListNodeUtils.print(root);
}
/** /**
* 递归法 * 递归法

View File

@ -0,0 +1,38 @@
package com.markilue.leecode.listnode.selftry;
import com.markilue.leecode.listnode.ListNode;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.listnode.selftry
*@Author: markilue
*@CreateTime: 2023-04-21 10:06
*@Description: TODO
*@Version: 1.0
*/
public class ReorderListII {
ListNode p;
public void reorderList(ListNode head) {
p = head;
recur(head);
}
public void recur(ListNode head) {
if (head == null) {
return;
}
recur(head.next);
if (p.next == null || head == p || head.next == p) {
//已经运行到了
p.next = null;
return;
}
head.next = p.next;
p.next = head;
p = p.next.next;
}
}

View File

@ -32,23 +32,23 @@ public class Question1 {
return o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0]; return o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0];
} }
}); });
int res=0; int res = 0;
ArrayList<int[]> single = new ArrayList<>(); ArrayList<int[]> single = new ArrayList<>();
ArrayList<int[]> multi = new ArrayList<>(); ArrayList<int[]> multi = new ArrayList<>();
for (int i = 0; i < nums.length; i++) { for (int i = 0; i < nums.length; i++) {
if(nums[i][0]<=nums[i-1][1]){ if (nums[i][0] <= nums[i - 1][1]) {
if(multi.size()>0&&nums[i][0]<multi.get(multi.size()-1)[1]){ if (multi.size() > 0 && nums[i][0] < multi.get(multi.size() - 1)[1]) {
nums[i][0] = multi.get(multi.size()-1)[1]; nums[i][0] = multi.get(multi.size() - 1)[1];
if(nums[i][1]<nums[i-1][1]){ if (nums[i][1] < nums[i - 1][1]) {
int[] temp = nums[i]; int[] temp = nums[i];
nums[i]=nums[i-1]; nums[i] = nums[i - 1];
nums[i-1]=temp; nums[i - 1] = temp;
} }
} }
if(nums[i-1][0]!=nums[i][0])single.add(new int[]{nums[i-1][0],nums[i][0]}); if (nums[i - 1][0] != nums[i][0]) single.add(new int[]{nums[i - 1][0], nums[i][0]});
if(nums[i][0]!=nums[i-1][1])multi.add(new int[]{nums[i][0],nums[i-1][1]}); if (nums[i][0] != nums[i - 1][1]) multi.add(new int[]{nums[i][0], nums[i - 1][1]});
}else { } else {
single.add(nums[i-1]); single.add(nums[i - 1]);
} }
} }
@ -71,7 +71,7 @@ public class Question1 {
public void test() { public void test() {
int[][] nums = new int[][]{{2, 5}, {8, 9}}; int[][] nums = new int[][]{{2, 5}, {8, 9}};
// int[][] nums = new int[][]{{4,8}, {1,6},{2,9}}; // int[][] nums = new int[][]{{4,8}, {1,6},{2,9}};
solve(nums); solve1(nums);
} }
public void solve(int[][] nums) { public void solve(int[][] nums) {
@ -93,7 +93,7 @@ public class Question1 {
for (int i = 1; i < nums.length; i++) { for (int i = 1; i < nums.length; i++) {
if (last[1] > nums[i][0]) { if (last[1] > nums[i][0]) {
total.add(new int[]{last[0], nums[i][0]-1}); total.add(new int[]{last[0], nums[i][0] - 1});
condition.add(1); condition.add(1);
if (nums[i][1] < last[1]) { if (nums[i][1] < last[1]) {
total.add(new int[]{nums[i][0], nums[i][1]}); total.add(new int[]{nums[i][0], nums[i][1]});
@ -119,14 +119,66 @@ public class Question1 {
for (int i = 0; i < total.size(); i++) { for (int i = 0; i < total.size(); i++) {
int[] ints = total.get(i); int[] ints = total.get(i);
Integer condition1 = condition.get(i); Integer condition1 = condition.get(i);
if(condition1==0){ if (condition1 == 0) {
result+=(ints[1]-ints[0]+1); result += (ints[1] - ints[0] + 1);
}else if(condition1==1){ } else if (condition1 == 1) {
result+=(ints[1]-ints[0]+1)*3; result += (ints[1] - ints[0] + 1) * 3;
}else { } else {
result+=(ints[1]-ints[0]+1)*4; result += (ints[1] - ints[0] + 1) * 4;
} }
} }
System.out.println(result); System.out.println(result);
} }
/**
* 后来重写的情况:两个用例应该是对了
* @param nums
*/
public void solve1(int[][] nums) {
Arrays.sort(nums, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0];
}
});
int[] last = nums[0];
int result = 0;
for (int i = 1; i < nums.length; i++) {
if (last[1] > nums[i][0]) {
if (nums[i][1] < last[0]) {
//特殊情况直接continue
continue;
} else if (nums[i][0] < last[0]) {
nums[i][0] = last[0];//直接归入
}
//计算单任务部分
result += (nums[i][0] - last[0]) * 3;
//计算多任务部分
if (nums[i][1] < last[1]) {
result += (nums[i][1] - nums[i][0] + 1) * 4;
last[0] = nums[i][1] + 1;
} else {
result += (last[1] - nums[i][0] + 1) * 4;
last[0] = last[1] + 1;
last[1] = nums[i][1];
}
} else {
//单任务部分
result += (last[1] - last[0] + 1) * 3;
//无任务部分
result += (nums[i][0] - last[1] - 1);
last = nums[i];
}
}
//最后加上单任务
result += (last[1] - last[0] + 1) * 3;
System.out.println(result);
}
} }