Skip to content

Commit

Permalink
LeetCode 每日一题 最长上升子序列
Browse files Browse the repository at this point in the history
  • Loading branch information
nibnait committed Mar 15, 2020
1 parent 70899bb commit 8d8c77d
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,54 +24,69 @@ public class M005_最长回文子串 extends TestCase {

@Test
public void testCase() {
// String str = "tattarrattat";
String str = "cabaddabacdd";
System.out.println(maxLcpsLength(str));

String str2 = "tattarrattat";
System.out.println(maxLcpsLength(str2));

String str3 = "babad";
System.out.println(maxLcpsLength(str3));

String str4 = "cbbd";
System.out.println(maxLcpsLength(str4));

}

public String longestPalindrome(String s) {


return "";
}

/**
* Manacher算法: 最长回文字串的长度
*
* 每个元素之间插入一个字符'#',抵消奇回文与偶回文的差别(任意字符都行,不会影响最终的计算结果)
* - pArr[i]:i位置上,所能扩到的最大回文半径
* - maxRight:记录回文半径扫到最右位置的下一个位置。(即将到达的位置)
* - index:当pR更新的时候,此时回文中心的位置
* <p>
* 每个元素之间插入一个字符'#',抵消奇回文与偶回文的差别(任意字符都行,不会影响最终的计算结果)
* - pArr[i]:i位置上,所能扩到的最大回文半径
* - maxRight:记录回文半径扫到最右位置的下一个位置。(即将到达的位置)
* - index:当pR更新的时候,此时回文中心的位置
*/
private int maxLcpsLength(String str) {
if (str==null || str.length()==0){
if (str == null || str.length() == 0) {
return 0;
}
char[] strArr = str.toCharArray();
int length = 2*strArr.length+1;
int length = 2 * strArr.length + 1;
char[] charArr = new char[length];
charArr[length-1] = '#';
charArr[length - 1] = '#';
//字符串预处理
int cnt = 0;
for (int i = 0; i < length-1; ) {
for (int i = 0; i < length - 1; ) {
charArr[i++] = '#';
charArr[i++] = strArr[cnt++];
}
int MaxLen = Integer.MIN_VALUE;
int[] pArr = new int[length]; //i位置上,所能扩到的最大回文半径
int maxRight = -1; //记录回文半径所能扫到最右位置。(maxRight = i+pArr[i]-1)
int index = -1; //当maxRight更新的时候,此时回文中心的位置
int index = -1; //当maxRight更新的时候,此时回文中心的位置
for (int i = 0; i < length; i++) {
if (i < maxRight){
pArr[i] = Math.min(pArr[2*index-i], maxRight-i); //看pArr[j]的长度
if (i < maxRight) {
pArr[i] = Math.min(pArr[2 * index - i], maxRight - i); //看pArr[j]的长度
} else {
pArr[i] = 1; //i在maxRight的右边,从1开始扩
}
//尝试扩展
while (i+pArr[i]<length && i-pArr[i]>=0 && charArr[i-pArr[i]]==charArr[i+pArr[i]]){
while (i + pArr[i] < length && i - pArr[i] >= 0 && charArr[i - pArr[i]] == charArr[i + pArr[i]]) {
pArr[i]++;
}
//尝试更新maxRight和index
if (i+pArr[i]>maxRight){
maxRight = i+pArr[i]-1;
if (i + pArr[i] > maxRight) {
maxRight = i + pArr[i] - 1;
index = i;
}
MaxLen = Math.max(MaxLen, pArr[i]);
}
return MaxLen-1; //因为MaxLen为带有'#'的回文半径,所以不带'#'回文长度也就为MaxLen-1
return MaxLen - 1; //因为MaxLen为带有'#'的回文半径,所以不带'#'回文长度也就为MaxLen-1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package algorithm_practice.LeetCode.code1000;

import common.util.StringUtil;
import junit.framework.TestCase;
import org.junit.Test;

/*
对于字符串 S 和 T,只有在 S = T + ... + T(T 与自身连接 1 次或多次)时,我们才认定 “T 能除尽 S”。
返回最长字符串 X,要求满足 X 能除尽 str1 且 X 能除尽 str2。
示例 1:
输入:str1 = "ABCABC", str2 = "ABC"
输出:"ABC"
示例 2:
输入:str1 = "ABABAB", str2 = "ABAB"
输出:"AB"
示例 3:
输入:str1 = "LEET", str2 = "CODE"
输出:""
 
提示:
1 <= str1.length <= 1000
1 <= str2.length <= 1000
str1[i] 和 str2[i] 为大写英文字母
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/greatest-common-divisor-of-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Created by nibnait on 2020-03-13
*/
public class E1071_字符串的最大公因子 extends TestCase {

@Test
public void testCase() {
String str1 = "ABCABC", str2 = "ABC";
System.out.println(gcdOfStrings(str1, str2));

String str3 = "ABABAB", str4 = "ABAB";
System.out.println(gcdOfStrings(str3, str4));

String str5 = "LEET", str6 = "CODE";
System.out.println(gcdOfStrings(str5, str6));

String str7 = "aaa", str8 = "";
System.out.println(gcdOfStrings(str7, str8));

String str9 = "", str0 = "aaa";
System.out.println(gcdOfStrings(str9, str0));


}

public String gcdOfStrings(String str1, String str2) {

String result = "";
if (str1.isEmpty() || str2.isEmpty()) {
return result;
}

if (!(str1 + str2).equals(str2 + str1)) {
return result;
}

int gcd = gcd(str1.length(), str2.length());
return str1.substring(0, gcd);
}

private int gcd(int len1, int len2) {
if (len2 > len1) {
return len1 == 0 ? len2 : gcd(len1, len2 % len1);
}
return len2 == 0 ? len1 : gcd(len2, len1 % len2);
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package algorithm_practice.LeetCode.code300;

import junit.framework.TestCase;
import org.junit.Test;

/*
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-increasing-subsequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Created by nibnait on 2020-03-14
*/
public class M300_最长上升子序列 extends TestCase {

@Test
public void testCase() {
int[] nums = new int[]{10, 9, 2, 5, 3, 7, 101, 18};
System.out.println(lengthOfLIS(nums));

}

/**
* 动态规划
*/
public int lengthOfLIS(int[] nums) {

if (nums.length == 0) {
return 0;
}

if (nums.length == 1) {
return 1;
}

int maxLen = 0;
// dp[i]: 前i个数字的最长子序列的长度
int[] dp = new int[nums.length];
for (int i = 0; i < dp.length; i++) {
dp[i] = 1;
}

for (int i = 1; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
maxLen = Math.max(maxLen, dp[i]);
}

return maxLen;
}
}
5 changes: 4 additions & 1 deletion src/main/java/algorithm_practice/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ split、正则匹配、
- [M093_复原IP地址](./LeetCode/code000/M093_复原IP地址.java)
- [M151_翻转字符串里的单词](./LeetCode/code100/M151_翻转字符串里的单词.java)
- [M060_第k个排列](./LeetCode/code000/M060_第k个排列.java)

- [E1071_字符串的最大公因子](./LeetCode/code1000/E1071_字符串的最大公因子.java)

## 数学
- [E1071_字符串的最大公因子](./LeetCode/code1000/E1071_字符串的最大公因子.java)

##
### 重建二叉树
Expand Down
39 changes: 0 additions & 39 deletions src/main/test/localtest/SetTest.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/**
* Created by nibnait on 2019-08-23
*/
public class BS extends TestCase {
public class 二分查找 extends TestCase {

@Test
public void testM() {
Expand Down
30 changes: 30 additions & 0 deletions src/main/test/practice/堆排序.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package practice;

import common.util.SysOut;
import junit.framework.TestCase;
import org.junit.Test;

/*
Created by nibnait on 2020-01-26
*/
public class 堆排序 extends TestCase {

@Test
public void testCase() {

// 73 为完全二叉树的根节点
int[] nums = new int[]{73, 98, 27, 36, 77, 22, 6, 32, 83, 69};
SysOut.printArray(nums);

nums = heapSort(nums);
SysOut.printArray(nums);

}

private int[] heapSort(int[] nums) {

return nums;
}

}

0 comments on commit 8d8c77d

Please sign in to comment.