leecode更新
This commit is contained in:
parent
667ca9a0b9
commit
381f8efdde
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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]
|
||||||
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue