modify code

master
algorithmzuo 3 years ago
parent c5b9e2d8d9
commit 7795d15cc0

@ -0,0 +1,137 @@
package class_2022_10_4_week;
// 来自华为
// 若两个正整数的和为素数,则这两个正整数称之为"素数伴侣"
// 给定N(偶数)个正整数中挑选出若干对,组成"素数伴侣"
// 例如有4个正整数25613
// 如果将5和6分为一组的话只能得到一组"素数伴侣"
// 如果将2和5、6和13编组将得到两组"素数伴侣"
// 这是得到"素数伴侣"最多的划分方案
// 输入:
// 有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。
// 输出:
// 输出一个整数 K ,表示最多能找出几对"素数伴侣"
// 数据范围: 1 <= n <= 100, 2 <= val <= 30000
// 测试链接 : https://www.nowcoder.com/practice/b9eae162e02f4f928eac37d7699b352e
// 请同学们务必参考如下代码中关于输入、输出的处理
// 这是输入输出处理效率很高的写法
// 提交以下的code提交时请把类名改成"Main",可以直接通过
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
import java.io.IOException;
public class Code01_MaxPrimePairs {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StreamTokenizer in = new StreamTokenizer(br);
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
while (in.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int) in.nval;
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
in.nextToken();
arr[i] = (int) in.nval;
}
int[][] graph = matrix(arr, n);
out.println(km(graph) / 2);
out.flush();
}
}
public static int[][] matrix(int[] arr, int n) {
int[][] ans = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
ans[i][j] = isPrime(arr[i] + arr[j]) ? 1 : 0;
}
}
return ans;
}
public static boolean isPrime(int num) {
int sqrt = (int) Math.sqrt(num);
for (int i = 2; i <= sqrt; i++) {
if (num % i == 0) {
return false;
}
}
return true;
}
public static int km(int[][] graph) {
int N = graph.length;
int[] match = new int[N];
int[] lx = new int[N];
int[] ly = new int[N];
boolean[] x = new boolean[N];
boolean[] y = new boolean[N];
int[] slack = new int[N];
int invalid = Integer.MAX_VALUE;
for (int i = 0; i < N; i++) {
match[i] = -1;
lx[i] = -invalid;
for (int j = 0; j < N; j++) {
lx[i] = Math.max(lx[i], graph[i][j]);
}
ly[i] = 0;
}
for (int from = 0; from < N; from++) {
for (int i = 0; i < N; i++) {
slack[i] = invalid;
}
Arrays.fill(x, false);
Arrays.fill(y, false);
while (!dfs(from, x, y, lx, ly, match, slack, graph)) {
int d = invalid;
for (int i = 0; i < N; i++) {
if (!y[i] && slack[i] < d) {
d = slack[i];
}
}
for (int i = 0; i < N; i++) {
if (x[i]) {
lx[i] = lx[i] - d;
}
if (y[i]) {
ly[i] = ly[i] + d;
}
}
Arrays.fill(x, false);
Arrays.fill(y, false);
}
}
int ans = 0;
for (int i = 0; i < N; i++) {
ans += (lx[i] + ly[i]);
}
return ans;
}
public static boolean dfs(int from, boolean[] x, boolean[] y, int[] lx, int[] ly, int[] match, int[] slack,
int[][] map) {
int N = map.length;
x[from] = true;
for (int to = 0; to < N; to++) {
if (!y[to]) {
int d = lx[from] + ly[to] - map[from][to];
if (d != 0) {
slack[to] = Math.min(slack[to], d);
} else {
y[to] = true;
if (match[to] == -1 || dfs(match[to], x, y, lx, ly, match, slack, map)) {
match[to] = from;
return true;
}
}
}
}
return false;
}
}

@ -0,0 +1,80 @@
package class_2022_10_4_week;
// 来自学员问题
// 给定一个二维数组matrix
// 每个格子都是正数,每个格子都和上、下、左、右相邻
// 你可以从任何一个格子出发,走向相邻的格子
// 把沿途的数字乘起来希望得到的最终数字中结尾的0最多
// 走的过程中,向左走或者向右走的拐点,最多只能有一次
// 返回结尾最多的0能是多少
// 1 <= 行、列 <= 400
public class Code02_MostTrailingZerosTurnLeftOfRightAtMostOnce {
public static int mostTrailingZeros(int[][] matrix) {
int n = matrix.length;
int m = matrix[0].length;
// f2[i][j] : matrix[i][j]自己有几个2的因子
int[][] f2 = new int[n][m];
// f5[i][j] : matrix[i][j]自己有几个5的因子
int[][] f5 = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
f2[i][j] = factors(matrix[i][j], 2);
f5[i][j] = factors(matrix[i][j], 5);
}
}
int[][] leftF2 = new int[n][m];
int[][] leftF5 = new int[n][m];
int[][] upF2 = new int[n][m];
int[][] upF5 = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
leftF2[i][j] = f2[i][j] + (j > 0 ? leftF2[i][j - 1] : 0);
leftF5[i][j] = f5[i][j] + (j > 0 ? leftF5[i][j - 1] : 0);
upF2[i][j] = f2[i][j] + (i > 0 ? upF2[i - 1][j] : 0);
upF5[i][j] = f5[i][j] + (i > 0 ? upF5[i - 1][j] : 0);
}
}
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
// 来到(i,j)
int l2 = j == 0 ? 0 : leftF2[i][j - 1];
int l5 = j == 0 ? 0 : leftF5[i][j - 1];
int r2 = leftF2[i][m - 1] - leftF2[i][j];
int r5 = leftF5[i][m - 1] - leftF5[i][j];
int u2 = i == 0 ? 0 : upF2[i - 1][j];
int u5 = i == 0 ? 0 : upF5[i - 1][j];
int d2 = upF2[n - 1][j] - upF2[i][j];
int d5 = upF5[n - 1][j] - upF5[i][j];
int p1 = Math.min(l2 + u2 + f2[i][j], l5 + u5 + f5[i][j]);
int p2 = Math.min(l2 + r2 + f2[i][j], l5 + r5 + f5[i][j]);
int p3 = Math.min(l2 + d2 + f2[i][j], l5 + d5 + f5[i][j]);
int p4 = Math.min(u2 + r2 + f2[i][j], u5 + r5 + f5[i][j]);
int p5 = Math.min(u2 + d2 + f2[i][j], u5 + d5 + f5[i][j]);
int p6 = Math.min(r2 + d2 + f2[i][j], r5 + d5 + f5[i][j]);
ans = Math.max(ans, Math.max(Math.max(p1, p2), Math.max(Math.max(p3, p4), Math.max(p5, p6))));
}
}
return ans;
}
public static int factors(int num, int f) {
int ans = 0;
while (num % f == 0) {
ans++;
num /= f;
}
return ans;
}
public static void main(String[] args) {
int[][] matrix1 = { { 5, 8, 3, 1 }, { 4, 15, 12, 1 }, { 6, 7, 10, 1 }, { 9, 1, 2, 1 } };
System.out.println(mostTrailingZeros(matrix1));
int[][] matrix2 = { { 7500, 10, 11, 12 }, { 6250, 13, 14, 15 }, { 134, 17, 16, 1 }, { 5500, 2093, 5120, 238 } };
System.out.println(mostTrailingZeros(matrix2));
}
}

@ -0,0 +1,68 @@
package class_2022_10_4_week;
import java.util.Arrays;
// 有一根长度为 n 个单位的木棍,棍上从 0 到 n 标记了若干位置
// 给你一个整数数组 cuts ,其中 cuts[i] 表示你需要将棍子切开的位置
// 你可以按顺序完成切割,也可以根据需要更改切割的顺序
// 每次切割的成本都是当前要切割的棍子的长度,切棍子的总成本是历次切割成本的总和
// 对棍子进行切割将会把一根木棍分成两根较小的木棍
// 这两根木棍的长度和就是切割前木棍的长度
// 返回切棍子的最小总成本
// 测试链接 : https://leetcode.cn/problems/minimum-cost-to-cut-a-stick/
public class Code03_MinimumCostToCutAStick {
// public static int zuo(int[] cuts, int n) {
// return f(cuts, 0, cuts.length - 1);
// }
//
// // cuts : 3 9 13 19 21
// // 0 1 2 3 4
// // 0,1 3,4
// // cuts[l....r]
// // 0...4 都切完!最小花费是多少
// // 1) 第一刀切在cuts[0] 3
// // 2) 第一刀切在cuts[1] 9
// // 3) 第一刀切在cuts[2] 9
// public static int f(int[] cuts, int l, int r) {
//
// }
public static int minCost(int n, int[] cuts) {
int m = cuts.length;
Arrays.sort(cuts);
int[] arr = new int[m + 2];
arr[0] = 0;
for (int i = 1; i <= m; ++i) {
arr[i] = cuts[i - 1];
}
arr[m + 1] = n;
int[][] dp = new int[m + 2][m + 2];
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= m; j++) {
dp[i][j] = -1;
}
}
return process(arr, 1, m, dp);
}
public static int process(int[] arr, int l, int r, int[][] dp) {
if (l > r) {
return 0;
}
if (l == r) {
return arr[r + 1] - arr[l - 1];
}
if (dp[l][r] != -1) {
return dp[l][r];
}
int ans = Integer.MAX_VALUE;
for (int k = l; k <= r; k++) {
// 左 | 右
ans = Math.min(ans, process(arr, l, k - 1, dp) + process(arr, k + 1, r, dp));
}
ans += arr[r + 1] - arr[l - 1];
dp[l][r] = ans;
return ans;
}
}

@ -0,0 +1,183 @@
package class_2022_10_4_week;
import java.util.Arrays;
// 来自拼多多
// 第一行有一个正整数n(3<=n<=100000)代表小A拟定的路线数量
// 第二行有n个正整数第i个代表第i条路线的起始日期
// 第三行有n个正整数第i个代表第i条路线的终止日期
// 输入保证起始日期小于终止日期
// 日期最小是1最大不超过1000000000
// 小A打算选三个路线进行旅游比如 A -> B -> C
// 要求A的结束日期要小于B的开始日期B的结束日期要小于C的开始日期
// 输出一个非负整数,代表线路的方案数量
// 例子
// 输入
// 6
// 4 1 3 2 1 2
// 4 1 3 3 2 2
// 输出
// 6
// 解释
// [1,1] -> [2,2] -> [3,3]
// [1,1] -> [2,2] -> [4,4]
// [1,1] -> [2,3] -> [4,4]
// [1,2] -> [3,3] -> [4,4]
// [1,1] -> [3,3] -> [4,4]
// [2,2] -> [3,3] -> [4,4]
public class Code04_NumberOfIncreasingRoadsThree {
// 暴力方法
// 为了验证
public static int num1(int[][] roads) {
int n = roads.length;
int max = 0;
for (int i = 0; i < n; i++) {
max = Math.max(max, roads[i][1]);
}
Arrays.sort(roads, (a, b) -> a[0] - b[0]);
int[][][] dp = new int[n][4][max + 1];
for (int a = 0; a < n; a++) {
for (int b = 0; b < 4; b++) {
for (int c = 0; c <= max; c++) {
dp[a][b][c] = -1;
}
}
}
return process1(roads, 0, 3, 0, dp);
}
public static int process1(int[][] roads, int i, int rest, int end, int[][][] dp) {
if (rest == 0) {
return 1;
}
if (i == roads.length) {
return 0;
}
if (dp[i][rest][end] != -1) {
return dp[i][rest][end];
}
int p1 = process1(roads, i + 1, rest, end, dp);
int p2 = roads[i][0] > end ? process1(roads, i + 1, rest - 1, roads[i][1], dp) : 0;
int ans = p1 + p2;
dp[i][rest][end] = ans;
return ans;
}
public static int num2(int[][] roads) {
int n = roads.length;
int[] sorted = new int[n << 1];
for (int i = 0; i < n; i++) {
sorted[i << 1] = roads[i][0];
sorted[i << 1 | 1] = roads[i][1];
}
Arrays.sort(roads, (a, b) -> a[0] - b[0]);
Arrays.sort(sorted);
IndexTree it1 = new IndexTree(n << 1);
IndexTree it2 = new IndexTree(n << 1);
IndexTree it3 = new IndexTree(n << 1);
for (int[] road : roads) {
int l = rank(sorted, road[0]);
int r = rank(sorted, road[1]);
it1.add(r, 1);
it2.add(r, it1.sum(l - 1));
it3.add(r, it2.sum(l - 1));
}
return it3.sum(n << 1);
}
public static int rank(int[] sorted, int num) {
int l = 0;
int r = sorted.length - 1;
int m = 0;
int ans = 0;
while (l <= r) {
m = (l + r) / 2;
if (sorted[m] >= num) {
ans = m;
r = m - 1;
} else {
l = m + 1;
}
}
return ans + 1;
}
// 下标从1开始
public static class IndexTree {
private int[] tree;
private int N;
public IndexTree(int size) {
N = size;
tree = new int[N + 1];
}
public int sum(int index) {
int ret = 0;
while (index > 0) {
ret += tree[index];
index -= index & -index;
}
return ret;
}
public void add(int index, int d) {
while (index <= N) {
tree[index] += d;
index += index & -index;
}
}
}
// 为了测试
public static int[][] randomRoads(int n, int v) {
int[][] roads = new int[n][2];
for (int i = 0; i < n; i++) {
int a = (int) (Math.random() * v) + 1;
int b = (int) (Math.random() * v) + 1;
int start = Math.min(a, b);
int end = Math.max(a, b);
if (start == end) {
end++;
}
roads[i][0] = start;
roads[i][1] = end;
}
return roads;
}
public static void main(String[] args) {
int N = 50;
int V = 50;
int testTime = 5000;
System.out.println("功能测试开始");
for (int i = 0; i < testTime; i++) {
int n = (int) (Math.random() * N) + 1;
int[][] roads = randomRoads(n, V);
int ans1 = num1(roads);
int ans2 = num2(roads);
if (ans1 != ans2) {
System.out.println("出错了!");
break;
}
}
System.out.println("功能测试结束");
System.out.println("性能测试开始");
int n = 100000;
int v = 1000000000;
int[][] roads = randomRoads(n, v);
System.out.println("数组长度 : " + n);
System.out.println("数值范围 : " + v);
long start = System.currentTimeMillis();
num2(roads);
long end = System.currentTimeMillis();
System.out.println("运行时间 : " + (end - start) + " 毫秒");
System.out.println("性能测试结束");
}
}

@ -0,0 +1,56 @@
package class_2022_10_4_week;
import java.util.HashMap;
// 给定一个字符串 s返回 s 中不同的非空 回文子序列 个数
// 通过从 s 中删除 0 个或多个字符来获得子序列
// 如果一个字符序列与它反转后的字符序列一致,那么它是 回文字符序列
// 如果有某个 i , 满足 ai != bi 则两个序列 a1, a2, ...  b1, b2, ... 不同
// 注意结果可能很大你需要对 10^9 + 7 取模
// 测试链接 : https://leetcode.cn/problems/count-different-palindromic-subsequences/
public class Code05_CountDifferentPalindromicSubsequences {
// 支持任意字符集
// 时间复杂度O(N^2)
public static int countPalindromicSubsequences(String str) {
int mod = 1000000007;
char[] s = str.toCharArray();
int n = s.length;
int[] right = new int[n];
int[] left = new int[n];
HashMap<Character, Integer> last = new HashMap<>();
for (int i = 0; i < n; i++) {
left[i] = last.getOrDefault(s[i], -1);
last.put(s[i], i);
}
last.clear();
for (int i = n - 1; i >= 0; i--) {
right[i] = last.getOrDefault(s[i], n);
last.put(s[i], i);
}
long[][] dp = new long[n][n];
for (int i = 0; i < n; i++) {
dp[i][i] = 1;
}
for (int i = n - 2; i >= 0; i--) {
for (int j = i + 1; j < n; j++) {
if (s[i] == s[j]) {
int l = Math.min(j, right[i]);
int r = Math.max(i, left[j]);
if (l > r) { // 内部不再有l和r位置的字符了
dp[i][j] = dp[i + 1][j - 1] * 2 + 2;
} else if (l == r) { // 内部仅有一个!
dp[i][j] = dp[i + 1][j - 1] * 2 + 1;
} else { // 内部有>=2个
dp[i][j] = dp[i + 1][j - 1] * 2 - dp[l + 1][r - 1] + mod;
}
} else {
dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1] + mod;
}
dp[i][j] %= mod;
}
}
return (int) dp[0][n - 1];
}
}

@ -0,0 +1,76 @@
package class_2022_10_4_week;
import java.util.HashMap;
import java.util.PriorityQueue;
// 来自学员问题
// 设计一个仓库管理器,提供如下的方法:
// 1) void supply(String item, int num, int price)
// 名字叫item的商品个数num价格price
// 2) int sell(String item, int num)
// 卖出叫item的商品个数num个价格从低到高返回卖出总价
// 如果商品很多,每种商品的数量可能很多,该怎么设计这个结构
public class Code06_StoreManager {
public static class StoreManager {
private HashMap<String, Store> map;
public StoreManager() {
map = new HashMap<>();
}
public void supply(String item, int num, int price) {
if (!map.containsKey(item)) {
map.put(item, new Store());
}
map.get(item).add(num, price);
}
public int sell(String item, int num) {
return map.get(item).remove(num);
}
}
public static class Store {
// 每一个价格,对应的数量
HashMap<Integer, Integer> priceNums;
// 价格组成的小根堆
PriorityQueue<Integer> heap;
public Store() {
priceNums = new HashMap<>();
heap = new PriorityQueue<>();
}
public void add(int num, int price) {
if (priceNums.containsKey(price)) {
priceNums.put(price, priceNums.get(price) + num);
} else {
priceNums.put(price, num);
heap.add(price);
}
}
public int remove(int num) {
int money = 0;
while (!heap.isEmpty() && num != 0) {
int price = heap.poll();
int stores = priceNums.get(price);
if (num >= stores) {
money += price * stores;
priceNums.remove(price);
num -= stores;
} else { // num < stores
money += price * num;
heap.add(price);
priceNums.put(price, stores - num);
break;
}
}
return money;
}
}
}

@ -0,0 +1,105 @@
package class_2022_10_4_week;
import java.util.HashMap;
import java.util.LinkedList;
// 来自亚马逊
// 给定一个数组arr和一个正数k
// 你可以随意删除arr中的数字最多删除k个
// 目的是让连续出现一种数字的长度尽量长
// 返回这个尽量长的长度
// 比如数组arr = { 3, -2, 3, 3, 5, 6, 3, -2 }, k = 3
// 你可以删掉-2、5、6(最多3个)这样数组arr = { 3, 3, 3, 3, -2 }
// 可以看到连续出现3的长度为4
// 这是所有删除方法里的最长结果所以返回4
// 1 <= arr长度 <= 3 * 10^5
// -10^9 <= arr中的数值 <= 10^9
// 0 <= k <= 3 * 10^5
public class Code07_RemoveMostKContinuousSameLongest {
// 暴力方法
// 为了测试
public static int longest1(int[] arr, int k) {
return process1(arr, 0, new int[arr.length], 0, k);
}
public static int process1(int[] arr, int i, int[] path, int size, int k) {
if (k < 0) {
return 0;
}
if (i == arr.length) {
if (size == 0) {
return 0;
}
int ans = 0;
int cnt = 1;
for (int j = 1; j < size; j++) {
if (path[j - 1] != path[j]) {
ans = Math.max(ans, cnt);
cnt = 1;
} else {
cnt++;
}
}
ans = Math.max(ans, cnt);
return ans;
} else {
path[size] = arr[i];
int p1 = process1(arr, i + 1, path, size + 1, k);
int p2 = process1(arr, i + 1, path, size, k - 1);
return Math.max(p1, p2);
}
}
// 正式方法
// 时间复杂度O(N)
public static int longest2(int[] arr, int k) {
HashMap<Integer, LinkedList<Integer>> valueIndies = new HashMap<>();
int ans = 1;
for (int i = 0; i < arr.length; i++) {
int value = arr[i];
if (!valueIndies.containsKey(value)) {
valueIndies.put(value, new LinkedList<>());
}
LinkedList<Integer> indies = valueIndies.get(value);
while (!indies.isEmpty() && i - indies.peekFirst() - indies.size() > k) {
indies.pollFirst();
}
indies.addLast(i);
ans = Math.max(ans, indies.size());
}
return ans;
}
// 为了测试
// 生成长度为n的数组
// 值在[-v,v]之间等概率随机
public static int[] randomArray(int n, int v) {
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = (int) (Math.random() * (2 * v + 1)) - v;
}
return ans;
}
// 为了测试
public static void main(String[] args) {
int N = 20;
int V = 10;
int K = 5;
int testTime = 5000;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int n = (int) (Math.random() * N) + 1;
int[] arr = randomArray(n, V);
int k = (int) (Math.random() * K);
int ans1 = longest1(arr, k);
int ans2 = longest2(arr, k);
if (ans1 != ans2) {
System.out.println("出错了!");
}
}
System.out.println("测试结束");
}
}

@ -2238,6 +2238,106 @@ n <= 3 * 10^5
第046节 2022年10月第3周流行算法题目解析
来自华为
若两个正整数的和为素数,则这两个正整数称之为"素数伴侣"
给定N(偶数)个正整数中挑选出若干对,组成"素数伴侣"
例如有4个正整数25613
如果将5和6分为一组的话只能得到一组"素数伴侣"
如果将2和5、6和13编组将得到两组"素数伴侣"
这是得到"素数伴侣"最多的划分方案
输入:
有一个正偶数 n ,表示待挑选的自然数的个数。后面给出 n 个具体的数字。
输出:
输出一个整数 K ,表示最多能找出几对"素数伴侣"
数据范围: 1 <= n <= 100, 2 <= val <= 30000
测试链接 : https://www.nowcoder.com/practice/b9eae162e02f4f928eac37d7699b352e
来自学员问题
给定一个二维数组matrix
每个格子都是正数,每个格子都和上、下、左、右相邻
你可以从任何一个格子出发,走向相邻的格子
把沿途的数字乘起来希望得到的最终数字中结尾的0最多
走的过程中,向左走或者向右走的拐点,最多只能有一次
返回结尾最多的0能是多少
1 <= 行、列 <= 400
有一根长度为 n 个单位的木棍,棍上从 0 到 n 标记了若干位置
给你一个整数数组 cuts ,其中 cuts[i] 表示你需要将棍子切开的位置
你可以按顺序完成切割,也可以根据需要更改切割的顺序
每次切割的成本都是当前要切割的棍子的长度,切棍子的总成本是历次切割成本的总和
对棍子进行切割将会把一根木棍分成两根较小的木棍
这两根木棍的长度和就是切割前木棍的长度
返回切棍子的最小总成本
测试链接 : https://leetcode.cn/problems/minimum-cost-to-cut-a-stick/
来自拼多多
第一行有一个正整数n(3<=n<=100000)代表小A拟定的路线数量
第二行有n个正整数第i个代表第i条路线的起始日期
第三行有n个正整数第i个代表第i条路线的终止日期
输入保证起始日期小于终止日期
日期最小是1最大不超过1000000000
小A打算选三个路线进行旅游比如 A -> B -> C
要求A的结束日期要小于B的开始日期B的结束日期要小于C的开始日期
输出一个非负整数,代表线路的方案数量
例子
输入
6
4 1 3 2 1 2
4 1 3 3 2 2
输出
6
解释
[1,1] -> [2,2] -> [3,3]
[1,1] -> [2,2] -> [4,4]
[1,1] -> [2,3] -> [4,4]
[1,2] -> [3,3] -> [4,4]
[1,1] -> [3,3] -> [4,4]
[2,2] -> [3,3] -> [4,4]
给定一个字符串 s返回 s 中不同的非空 回文子序列 个数
通过从 s 中删除 0 个或多个字符来获得子序列
如果一个字符序列与它反转后的字符序列一致,那么它是 回文字符序列
如果有某个 i , 满足 ai != bi 则两个序列 a1, a2, ...  b1, b2, ... 不同
注意结果可能很大你需要对 10^9 + 7 取模
测试链接 : https://leetcode.cn/problems/count-different-palindromic-subsequences/
来自学员问题
设计一个仓库管理器,提供如下的方法:
1) void supply(String item, int num, int price)
名字叫item的商品个数num价格price
2) int sell(String item, int num)
卖出叫item的商品个数num个价格从低到高返回卖出总价
如果商品很多,每种商品的数量可能很多,该怎么设计这个结构
来自亚马逊
给定一个数组arr和一个正数k
你可以随意删除arr中的数字最多删除k个
目的是让连续出现一种数字的长度尽量长
返回这个尽量长的长度
比如数组arr = { 3, -2, 3, 3, 5, 6, 3, -2 }, k = 3
你可以删掉-2、5、6(最多3个)这样数组arr = { 3, 3, 3, 3, -2 }
可以看到连续出现3的长度为4
这是所有删除方法里的最长结果所以返回4
1 <= arr长度 <= 3 * 10^5
-10^9 <= arr中的数值 <= 10^9
0 <= k <= 3 * 10^5

Loading…
Cancel
Save