leecode更新

This commit is contained in:
markilue 2023-02-28 14:30:04 +08:00
parent 667ca9a0b9
commit 381f8efdde
4 changed files with 369 additions and 3 deletions

View File

@ -60,7 +60,7 @@ public class Example4 {
@Override @Override
public void process(String s, Context context, Iterable<Tuple2<String, Long>> iterable, Collector<String> collector) throws Exception { public void process(String s, Context context, Iterable<Tuple2<String, Long>> iterable, Collector<String> collector) throws Exception {
//初始化一个窗口状态变量注意:窗口状态变量的可见范围是当前窗口 //初始化一个窗口状态变量注意:窗口状态变量的可见范围是当前窗口(无论窗口是否被销毁)
ValueState<Boolean> firstCalculate = context.windowState().getState(new ValueStateDescriptor<Boolean>("first", Types.BOOLEAN)); ValueState<Boolean> firstCalculate = context.windowState().getState(new ValueStateDescriptor<Boolean>("first", Types.BOOLEAN));
if (firstCalculate.value() == null) { if (firstCalculate.value() == null) {

View File

@ -83,8 +83,6 @@ public class Example9 {
+I[Bob, 2, 1970-01-01T15:00] +I[Bob, 2, 1970-01-01T15:00]
+I[Mary, 1, 1970-01-01T15:00] +I[Mary, 1, 1970-01-01T15:00]
+I[liz, 1, 1970-01-01T15:00] +I[liz, 1, 1970-01-01T15:00]
*/ */

View File

@ -0,0 +1,191 @@
package com.markilue.leecode.hot100;
import org.junit.Test;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-02-28 10:10
*@Description:
* TODO 力扣5题 最长回文子串:
* 给你一个字符串 s找到 s 中最长的回文子串
* 如果字符串的反序与原始字符串相同则该字符串称为回文字符串
*@Version: 1.0
*/
public class T05_LongestPalindrome {
@Test
public void test() {
String s = "babad";
System.out.println(longestPalindrome1(s));
}
/**
* 思路:最长回文子串则不能删除一旦不是回文子串则直接归零
* TODO DP五部曲:
* 1.dp定义:dp[i][j]表示以j开始以i结尾的子串是不是回文子串
* 2.dp状态转移方程:
* 1.char[i]==char[j]
* dp[i][j]=dp[i-1][j+1]
* 3.dp初始化: dp[i][i]=true
* 4.dp遍历顺序:从上往下
* 5.dp举例推导:
* 速度击败51.19% 内存击败7.46% 79ms
* 修改后 62ms
* @param s
* @return
*/
public String longestPalindrome(String s) {
char[] chars = s.toCharArray();
boolean[][] dp = new boolean[chars.length][chars.length];
int maxLength = 0;
int begin = 0;
int end = 0;
for (int i = 0; i < chars.length; i++) {
for (int j = 0; j <= i; j++) {
if (chars[i] == chars[j]) {
if (i <= j + 1) {
dp[i][j] = true;
} else {
dp[i][j] = dp[i - 1][j + 1];
}
}
if (dp[i][j]) {
if (maxLength < i - j + 1) {
maxLength = i - j + 1;
begin = j;
end = i + 1;
}
}
}
}
return s.substring(begin, end);
}
public boolean isPalindrome(char[] chars, int start, int end) {
while (start < end) {
if (chars[start++] != chars[end--]) return false;
}
return true;
}
/**
* 一维dp优化
* 速度击败54.74% 内存击败77.79% 42ms
* @param s
* @return
*/
public String longestPalindrome1(String s) {
char[] chars = s.toCharArray();
boolean[] dp = new boolean[chars.length];
int maxLength = 0;
int begin = 0;
for (int i = 0; i < chars.length; i++) {
for (int j = 0; j <= i; j++) {
if (chars[i] == chars[j]) {
if (i <= j + 1) {
dp[j] = true;
} else {
dp[j] = dp[j + 1];
}
}else {
dp[j]=false;
}
if (dp[j]&&maxLength < i - j + 1) {
maxLength = i - j + 1;
begin = j;
}
}
}
return s.substring(begin, begin+maxLength);
}
/**
* 官方最快:
* 分别计算考虑左边考虑右边和以i为中心本质上应该还是O(N^2)
* 速度击败93.2% 内存击败78.66% 7ms
* @param s
* @return
*/
public String longestPalindrome2(String s) {
char[] charStr = s.toCharArray();
int maxlen = 0;
int maxStart = 0;
for (int i = 0; i < charStr.length; i++) {
int len = 1;
int left = i - 1;
int right = i + 1;
while (left >= 0 && charStr[i] == charStr[left]) {//查找左边
len++;
left--;
}
while (right < charStr.length && charStr[i] == charStr[right]) {//查找右边
len++;
right++;
}
while (left >= 0 && right < charStr.length && charStr[left] == charStr[right]) {//以i为中心
len += 2;
left--;
right++;
}
if (len > maxlen) {
maxlen = len;
maxStart = left;
}
}
return s.substring(maxStart + 1, maxlen + maxStart + 1);
}
/**
* 中心扩展法:看以两个为中心和以一个为中心是不是回文子串
* @param s
* @return
*/
public String longestPalindrome3(String s) {
if (s == null || s.length() < 1) {
return "";
}
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > end - start) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
public int expandAroundCenter(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
--left;
++right;
}
return right - left - 1;
}
}

View File

@ -0,0 +1,177 @@
package com.markilue.leecode.hot100;
import com.sun.java.swing.plaf.windows.WindowsDesktopIconUI;
import org.junit.Test;
import java.util.Arrays;
/**
*@BelongsProject: Leecode
*@BelongsPackage: com.markilue.leecode.hot100
*@Author: markilue
*@CreateTime: 2023-02-28 11:52
*@Description:
* TODO 力扣6题 N字形变形:
* 将一个给定字符串 s 根据给定的行数 numRows 以从上往下从左到右进行 Z 字形排列
* 比如输入字符串为 "PAYPALISHIRING" 行数为 3 排列如下
* P A H N
* A P L S I I G
* Y I R
* 之后你的输出需要从左往右逐行读取产生出一个新的字符串比如"PAHNAPLSIIGYIR"
* 请你实现这个将字符串进行指定行数变换的函数
* string convert(string s, int numRows);
*@Version: 1.0
*/
public class T06_Convert {
@Test
public void test() {
// String s = "ABC";
String s = "PAYPALISHIRING";
System.out.println(convert3(s, 3));
}
/**
* 思路:先计算一共需要多少列才能记录
* 速度击败21.1% 内存击败22.88% 26ms
* @param s
* @param numRows
* @return
*/
public String convert(String s, int numRows) {
//先计算一共需要多少列才能记录
int length = s.length();
if (numRows >= length || numRows == 1) return s;
char[] chars1 = s.toCharArray();
int index = 0;
int col = length / 2;
char[][] chars = new char[numRows][col + 1];
for (int k = 0; k < length / (numRows - 1) && index < length; k++) {
int i = 0;
int j = 0;
for (; i < numRows - 1 && index < length; i++) {
chars[i][k * (numRows - 1)] = chars1[index++];
}
for (; i > 0 && index < length; i--, j++) {
chars[i][k * (numRows - 1) + j] = chars1[index++];
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
for (int j = 0; j < chars[i].length; j++) {
if (chars[i][j] != '\u0000')
sb.append(chars[i][j]);
}
}
return sb.toString();
}
/**
* 官方思路:本质上和自己的是一致的但是判断依据进行了简化
* 速度击败18.75% 内存击败12.36% 35ms
* @param s
* @param numRows
* @return
*/
public String convert1(String s, int numRows) {
int n = s.length(), r = numRows;
if (r == 1 || r >= n) {
return s;
}
int t = r * 2 - 2;
int c = (n + t - 1) / t * (r - 1);
char[][] mat = new char[r][c];
for (int i = 0, x = 0, y = 0; i < n; ++i) {
mat[x][y] = s.charAt(i);
if (i % t < r - 1) {
++x; // 向下移动
} else {
--x;
++y; // 向右上移动
}
}
StringBuffer ans = new StringBuffer();
for (char[] row : mat) {
for (char ch : row) {
if (ch != 0) {
ans.append(ch);
}
}
}
return ans.toString();
}
/**
* 思路:直接使用stringbuilder进行append
* 速度击败43.99% 内存击败56.51% 8ms
* @param s
* @param numRows
* @return
*/
public String convert2(String s, int numRows) {
int n = s.length(), r = numRows;
if (r == 1 || r >= n) {
return s;
}
StringBuffer[] mat = new StringBuffer[r];
for (int i = 0; i < r; ++i) {
mat[i] = new StringBuffer();
}
for (int i = 0, x = 0, t = r * 2 - 2; i < n; ++i) {
mat[x].append(s.charAt(i));
if (i % t < r - 1) {
++x;
} else {
--x;
}
}
StringBuffer ans = new StringBuffer();
for (StringBuffer row : mat) {
ans.append(row);
}
return ans.toString();
}
/**
* 官方直接构造法:
* 把其中的0,1,2,3改成循环的i变量就是代码 吐槽一句这个表格编辑的时候看起来整齐预览却不整齐调整了好半天官方大大能不能优化一下
* 0 0+t 0+2t 0+3t
* 1 t-1 1+t 0+2t-1 1+2t 0+3t-1 1+3t
* 2 t-2 2+t 0+2t-2 2+2t 0+3t-2 2+3t
* 3 3+t 3+2t 3+3t
* 好像暂时有错误
* @param s
* @param numRows
* @return
*/
public String convert3(String s, int numRows) {
int n = s.length(), r = numRows;
if (r == 1 || r >= n) {
return s;
}
StringBuilder sb = new StringBuilder();
int t = r * 2 - 2;
for (int i = 0; i < r; i++) {// 枚举矩阵的行
for (int j = 0; j + i < n; j += t) {// 枚举每个周期的起始下标
sb.append(s.charAt(j + i));// 当前周期的第一个字符
if (0 < i && i < r - 1 && j + t - i < n) {
sb.append(s.charAt(j + t - 1));// 当前周期的第二个字符
}
}
}
return sb.toString();
}
}