leecode更新
This commit is contained in:
parent
4032d74f99
commit
69049a5e86
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-12 10:58
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣128题 最长连续序列:
|
||||||
|
* 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
|
||||||
|
* 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T50_LongestConsecutive {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
int[] nums = {};
|
||||||
|
System.out.println(longestConsecutive(nums));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:排序后连续,但是时间复杂度O(n)
|
||||||
|
* 速度击败99.86% 内存击败91.74% 11ms
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int longestConsecutive(int[] nums) {
|
||||||
|
if (nums == null || nums.length == 0) return 0;
|
||||||
|
|
||||||
|
Arrays.sort(nums);
|
||||||
|
|
||||||
|
int max = 1;
|
||||||
|
int cur = 1;
|
||||||
|
|
||||||
|
for (int i = 1; i < nums.length; i++) {
|
||||||
|
if (nums[i] == nums[i - 1] + 1) {
|
||||||
|
cur++;
|
||||||
|
} else if (nums[i] == nums[i - 1]) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
cur = 1;
|
||||||
|
}
|
||||||
|
if (cur > max) max = cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方题解:哈希表 时间复杂度O(n)
|
||||||
|
* 速度击败78.83% 内存击败28.14% 19ms
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int longestConsecutive1(int[] nums) {
|
||||||
|
Set<Integer> num_set = new HashSet<Integer>();
|
||||||
|
for (int num : nums) {
|
||||||
|
num_set.add(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
int longestStreak = 0;
|
||||||
|
|
||||||
|
for (int num : num_set) {
|
||||||
|
if (!num_set.contains(num - 1)) {
|
||||||
|
int currentNum = num;
|
||||||
|
int currentStreak = 1;
|
||||||
|
|
||||||
|
while (num_set.contains(currentNum + 1)) {
|
||||||
|
currentNum += 1;
|
||||||
|
currentStreak += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
longestStreak = Math.max(longestStreak, currentStreak);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return longestStreak;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-12 11:25
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣136题 只出现一次的数字:
|
||||||
|
* 给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
|
||||||
|
* 你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T51_SingleNumber {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:使用hashset去重,最后还在hashset中的就是剩下的
|
||||||
|
* 速度击败19.56% 内存击败46.55% 10ms
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int singleNumber(int[] nums) {
|
||||||
|
|
||||||
|
Set<Integer> set = new HashSet<>();
|
||||||
|
|
||||||
|
for (int num : nums) {
|
||||||
|
if (set.contains(num)) {
|
||||||
|
set.remove(num);
|
||||||
|
} else {
|
||||||
|
set.add(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int result = 0;
|
||||||
|
for (Integer integer : set) {
|
||||||
|
result = integer;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方思路:位运算去重
|
||||||
|
* 速度击败99.99% 内存击败44.28% 1ms
|
||||||
|
* @param nums
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int singleNumber1(int[] nums) {
|
||||||
|
|
||||||
|
int singleNumber = 0;
|
||||||
|
for (int num : nums) {
|
||||||
|
singleNumber = singleNumber ^ num;
|
||||||
|
}
|
||||||
|
return singleNumber;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-12 11:44
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣139题 单词拆分:
|
||||||
|
* 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
|
||||||
|
* 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T52_WordBreak {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
String s = "leetcode";
|
||||||
|
List<String> dict = Arrays.asList("leet", "code");
|
||||||
|
System.out.println(wordBreak(s, dict));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:动态规划法,依次判断当前位置能否使用word拼接出来
|
||||||
|
* 速度击败88.38% 内存击败89.96%
|
||||||
|
* @param s
|
||||||
|
* @param wordDict
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean wordBreak(String s, List<String> wordDict) {
|
||||||
|
|
||||||
|
boolean[] dp = new boolean[s.length() + 1];
|
||||||
|
dp[0] = true;
|
||||||
|
for (int i = 1; i < dp.length; i++) {
|
||||||
|
for (int j = 0; j < wordDict.size(); j++) {
|
||||||
|
String word = wordDict.get(j);
|
||||||
|
int length = word.length();
|
||||||
|
if (i >= length) dp[i] |= dp[i - length] && word.equals(s.substring(i - length, i));
|
||||||
|
if (dp[i]) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[s.length()];
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 以前的一些写法:本质上类似,但是if变简单了,不需要次次都判断了,直接dp[i]=true
|
||||||
|
* @param s
|
||||||
|
* @param wordDict
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean wordBreak1(String s, List<String> wordDict) {
|
||||||
|
boolean[] dp = new boolean[s.length() + 1];
|
||||||
|
dp[0] = true;
|
||||||
|
|
||||||
|
for (int i = 1; i <= s.length(); i++) {
|
||||||
|
for (String word : wordDict) {
|
||||||
|
int len = word.length();
|
||||||
|
if (i >= len && dp[i - len] && word.equals(s.substring(i - len, i))) {
|
||||||
|
dp[i] = true;//
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dp[s.length()];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 官方最快:回溯+记忆化搜索
|
||||||
|
* @param s
|
||||||
|
* @param wordDict
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean wordBreak2(String s, List<String> wordDict) {
|
||||||
|
int[] memo = new int[s.length()];
|
||||||
|
Arrays.fill(memo, -1);
|
||||||
|
return check(s, 0, wordDict, memo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean check(String s, int idx, List<String> wordDict, int[] memo) {
|
||||||
|
if (idx == s.length()) return true;
|
||||||
|
if (memo[idx] != -1) return memo[idx] != 0;//记忆化回溯
|
||||||
|
for (String word : wordDict)
|
||||||
|
if (s.startsWith(word, idx) && check(s, idx + word.length(), wordDict, memo)) {//找到了,就check后面行不行
|
||||||
|
memo[idx] = 1;//找到了
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//没找到
|
||||||
|
memo[idx] = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import com.markilue.leecode.listnode.ListNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-12 12:20
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣141 环形链表:
|
||||||
|
* 给你一个链表的头节点 head ,判断链表中是否有环。
|
||||||
|
* 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。
|
||||||
|
* 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
|
||||||
|
* 注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
|
||||||
|
* 如果链表中存在环 ,则返回 true 。 否则,返回 false 。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T53_HasCycle {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:简单题 快慢指针 一个走一步,一个走两步,如果有环则一定相遇
|
||||||
|
* 速度击败100% 内存击败74.13% 0ms
|
||||||
|
* @param head
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean hasCycle(ListNode head) {
|
||||||
|
|
||||||
|
ListNode fast = head;
|
||||||
|
ListNode slow = head;
|
||||||
|
|
||||||
|
while (fast != null && fast.next != null) {
|
||||||
|
fast = fast.next.next;
|
||||||
|
slow = slow.next;
|
||||||
|
if (fast == slow) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.markilue.leecode.hot100;
|
||||||
|
|
||||||
|
import com.markilue.leecode.listnode.ListNode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@BelongsProject: Leecode
|
||||||
|
*@BelongsPackage: com.markilue.leecode.hot100
|
||||||
|
*@Author: markilue
|
||||||
|
*@CreateTime: 2023-03-12 12:34
|
||||||
|
*@Description:
|
||||||
|
* TODO 力扣142题 环形链表II:
|
||||||
|
* 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
|
||||||
|
* 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。
|
||||||
|
* 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
|
||||||
|
* 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
|
||||||
|
* 不允许修改 链表。
|
||||||
|
*@Version: 1.0
|
||||||
|
*/
|
||||||
|
public class T54_DetectCycle {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 思路:快慢指针法,先相遇,再让他走x步和从头出发的相遇
|
||||||
|
* 速度击败100% 内存击败68.41%
|
||||||
|
* @param head
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ListNode detectCycle(ListNode head) {
|
||||||
|
|
||||||
|
ListNode fast = head;
|
||||||
|
ListNode slow = head;
|
||||||
|
|
||||||
|
while (fast != null && fast.next != null) {
|
||||||
|
//有环则一定不会等于null
|
||||||
|
fast = fast.next.next;
|
||||||
|
slow = slow.next;
|
||||||
|
|
||||||
|
if (fast == slow) {
|
||||||
|
//两者相遇了
|
||||||
|
//从头出发一个,从相遇位置出发一个
|
||||||
|
ListNode start = head;
|
||||||
|
ListNode meet = fast;
|
||||||
|
while (start != meet) {
|
||||||
|
start = start.next;
|
||||||
|
meet = meet.next;
|
||||||
|
}
|
||||||
|
return meet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;//没有相遇
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue