LeetCode Biweekly Contest 58
最后一题,算法知道就会做,不知道不会做
T1: Delete Characters to Make Fancy String
删除字符保证不出现连续3个相同字符的字符串,暴力模拟即可
T2: Check if Move is Legal
8*8的矩阵,给定一个位置,问8个方向中是否存在一个方向有一个大于3的区间, 中间的颜色一样,但和两头的颜色不一致。暴力模拟判断即可
T3: Minimum Total Space Wasted With K Resizing Operations
动态规划解决:F[i][k]表示前i个数组,改变了k次的最小值多少,提前做好预处理即可:
public int minSpaceWastedKResizing(int[] nums, int k) {
int n = nums.length;
int[][] sum = new int[n][n];
for(int i=0;i<n;i++) {
int max = nums[i];
int cnt = nums[i];
sum[i][i] = 0;
for(int j=i+1;j<n;j++) {
max = Math.max(max, nums[j]);
cnt += nums[j];
sum[i][j] = max * (j-i+1) - cnt;
}
}
int[][] fn = new int[n][k+1];
for(int i=0;i<n;i++) {
fn[i][0] = sum[0][i];
for(int tk=1;tk<=k;tk++) {
fn[i][tk] = sum[0][i];
for(int j=i-1;j>=0;j--) {
fn[i][tk] = Math.min(fn[i][tk], fn[j][tk-1] + sum[j+1][i]);
}
}
}
return fn[n-1][k];
}
T4: Maximum Product of the Length of Two Palindromic Substirngs
给定一个字符串,然后找出2个奇数的回文子串,其长度相乘最大。 Manacher’s算法,会就会,不会就不会(白给)
public long maxProduct(String s) {
int n = s.length();
int[] p = new int[n];
int mx = 0;
int center = 0;
for(int i=0;i<n;i++) {
p[i] = mx > i ? Math.min(p[2 * center - i], mx - i) : 0;
while (i+p[i]+1<n && i-p[i]-1>=0 && s.charAt(i+p[i]+1) == s.charAt(i-p[i]-1)) {
p[i]++;
}
if (mx < i+ p[i]) {
mx = i + p[i];
center = i;
}
}
long[] fnl = new long[n];
long[] fnr = new long[n];
LinkedList<Integer> que = new LinkedList<>();
fnl[0] = 1;
que.add(0);
for(int i=1;i<n;i++){
fnl[i] = 1;
while(! que.isEmpty()) {
int x = que.getFirst();
if (x+p[x] < i) {
que.removeFirst();
} else {
fnl[i] = 2L * (Math.min(i, x+p[x]) - x) + 1;
break;
}
}
que.add(i);
fnl[i] = Math.max(fnl[i], fnl[i-1]);
}
que.clear();
fnr[n-1] = 1;
que.add(n-1);
for(int i=n-2;i>=0;i--) {
fnr[i] = 1;
while(! que.isEmpty()) {
int x = que.getFirst();
if (x - p[x] > i) {
que.removeFirst();
} else {
fnr[i] = 2L * (x - Math.max(i, x - p[x])) + 1;
break;
}
}
que.add(i);
fnr[i] = Math.max(fnr[i], fnr[i+1]);
}
long ans = 0;
for(int i=0;i<n-1;i++) {
ans = Math.max(ans, fnl[i] * fnr[i+1]);
}
return ans;
}