当前位置:网站首页>522. 最长特殊序列 II / 剑指 Offer II 101. 分割等和子集
522. 最长特殊序列 II / 剑指 Offer II 101. 分割等和子集
2022-06-27 14:03:00 【彼淇梁】
522. 最长特殊序列 II【中等题】【每日一题】
思路:【枚举】
过程写在代码注释里,参考自官方题解。但我的执行耗时是2ms~
代码:
class Solution {
public int findLUSlength(String[] strs) {
/** * 对字符串数组中某一字符串 strs[i] 来说 如果它的一个子序列 sub 是特殊序列,即不为数组中其他字符串的子序列 * 那么这个字符串 strs[i]也是一个特殊序列 * 证明:反证法 * 假设 sub 为特殊序列,那么 sub 在其他字符串中均不会以子序列形式出现 * 那么给 sub 添加任意个字符,它依然不会以子序列形式出现在其他字符串中 * 由于题目要求寻找最长特殊序列,因此我们只需枚举数组中每个字符串,筛选出长度最长的符合特殊序列的字符串,即为我们要寻找的最长特殊序列 * 于是现在问题简化为两步: * 1.遍历每个字符串,判断其是否特殊序列 * 2.如果字符串满足特殊序列要求,更新最长特殊序列长度 max,函数最后返回 max * 对于第1步来说,可以转化为,判断当前字符串是否是数组中除自己之外的其他字符串的子序列,是 则说明当前字符串是特殊序列,否 则说明不是特殊序列 */
int max = -1,n = strs.length;
//双循环遍历字符串数组,筛选strs[i]是否是特殊序列
for (int i = 0; i < n; i++) {
boolean flag = true;
for (int j = 0; j < n; j++) {
if (i == j){
continue;
}
String s1 = strs[i],s2 = strs[j];
int n1 = s1.length(),n2 = s2.length();
//s1的长度比s2还长,s1不可能是s2的子序列,不用接着判断了
if (n1 > n2){
continue;
}else if (n1 == n2){
//s1的长度与s2相等
//如果s1与s2不等,则s1不是s2的子序列
//如果s1与s2相等,则s1是s2的子序列,标志位置为flase,内层for循环退出
if (s1.equals(s2)){
flag = false;
break;
}else {
continue;
}
}
//判断s1是否是s2的子序列(此时 n1 < n2)
int p1 = 0,p2 = 0;
while (p1 < n1 && p2 < n2){
//如果p1字符与p2字符相等,则p1与p2均右移
if (s1.charAt(p1) == s2.charAt(p2)){
p1++;
p2++;
}else {
//否则,只将p2右移
p2++;
}
}
//如果s1正常遍历结束,说明s1是s2的子序列,标志位置为false,内层for循环退出
if (p1 == n1){
flag = false;
break;
}
}
//经过筛选,strs[i]经受住了考验,是特殊序列,则更新最长特殊序列的长度
if (flag){
max = Math.max(max,strs[i].length());
}
}
return max;
}
}
剑指 Offer II 101. 分割等和子集【简单题】
思路:【动态规划】
一阶dp和二阶dp,均看答案写~,这是个动态规划题我是真没想到。
代码:【二阶dp】
class Solution {
public boolean canPartition(int[] nums) {
//要分成两部分,那么数组长度至少为2,
int n = nums.length;
if (n < 2){
return false;
}
//要分成等和的两部分,那每一部分的和肯定是总和的一半,所以应该先求出数组的总和sum,这样就找到了目标和
int sum = 0,max = 0;
for (int num : nums) {
max = Math.max(max,num);
sum += num;
}
//如果sum是奇数,那么数组肯定不可能被分为元素和相等的两部分
if(sum % 2 != 0){
return false;
}
int target = sum / 2;
//max > target,不可能将数组分为元素和相等的两部分
if (max > target){
return false;
}
//max == target 一定可以分为两部分,max为一部分,其余元素为另一部分
if (max == target){
return true;
}
//定义dp数组 dp[i][j]表示数组下标 [0,i) 范围内,选取若干个元素是否能使元素和达到j 那么我们只需要求出dp[n-1][target]是否为true即可
boolean[][] dp = new boolean[n][target+1];
//边界条件: j=0时,dp[i][0] = true ; i=0时,dp[0][nums[0]] = true。
dp[0][nums[0]] = true;
for (int i = 0; i < n; i++) {
dp[i][0] = true;
}
for (int i = 1; i < n; i++) {
for (int j = 1; j <= target; j++) {
if (j >= nums[i]){
//不选择nums[i]元素,则dp[i][j]取决于 dp[i-1][j]
//选择 nums[i]元素,则dp[i][j]取决于 dp[i-1][j-nums[i]]
dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i]];
}else {
//由于 j < nums[i] 不可能选择nums[i]元素
dp[i][j] = dp[i-1][j];
}
}
}
return dp[n-1][target];
}
}
代码:【一阶dp】
class Solution {
public boolean canPartition(int[] nums) {
//要分成两部分,那么数组长度至少为2,
int n = nums.length;
if (n < 2){
return false;
}
//要分成等和的两部分,那每一部分的和肯定是总和的一半,所以应该先求出数组的总和sum,这样就找到了目标和
int sum = 0,max = 0;
for (int num : nums) {
max = Math.max(max,num);
sum += num;
}
//如果sum是奇数,那么数组肯定不可能被分为元素和相等的两部分
if(sum % 2 != 0){
return false;
}
int target = sum / 2;
//max > target,不可能将数组分为元素和相等的两部分
if (max > target){
return false;
}
//max == target 一定可以分为两部分,max为一部分,其余元素为另一部分
if (max == target){
return true;
}
//定义dp数组 dp[j]表示当前数组可选范围内,选择若干个元素是否能使元素和达到j,那么我们求出当可选范围为整个数组时,dp[target]是否为true即可
boolean[] dp = new boolean[target+1];
//边界条件:j = 0 时,必为 true
dp[0] = true;
for (int num : nums) {
for (int j = target; j >= num; j--) {
/*if (j >= nums[i]){ //选择nums[i]元素,则dp[j]取决于dp[j-nums[i]] //不选择nums[i]元素,则dp[j]不动 dp[j] = dp[j] || dp[j-nums[i]]; }else { //j < nums[i]时,不可能选择nums[i] 于是 dp[j]保持不动 dp[j] = dp[j]; } 于是转移方程整理归纳如下 */
dp[j] = dp[j] || dp[j - num];
}
}
return dp[target];
}
}
边栏推荐
- Domestic database disorder
- 为什么 Oracle 云客户必须在Oracle Cloud 季度更新发布后自行测试?
- 命令行编辑器 sed 基础用法总结
- buuctf misc 百里挑一
- 解析Activity启动-生命周期角度
- MySQL 索引及其分类
- 如何使用200行代码实现Scala的对象转换器
- Deep understanding of bit operations
- 芯片供给过剩之际,进口最多的中国继续减少进口,美国芯片慌了
- Principle Comparison and analysis of mechanical hard disk and SSD solid state disk
猜你喜欢

深入理解位运算

Rereading the classic: the craft of research (1)

Tsinghua & Shangtang & Shanghai AI & CUHK proposed Siamese image modeling, which has both linear probing and intensive prediction performance
![[PHP code injection] common injectable functions of PHP language and utilization examples of PHP code injection vulnerabilities](/img/19/9827a5e8becfc9d5bf2f51bddf803e.png)
[PHP code injection] common injectable functions of PHP language and utilization examples of PHP code injection vulnerabilities

隱私計算FATE-離線預測

全球芯片市场或陷入停滞,中国芯片逆势扩张加速提升自给率

CMOS级电路分析
![[OS command injection] common OS command execution functions and OS command injection utilization examples and range experiments - based on DVWA range](/img/f2/458770fc74971bef23f96f87733ee5.png)
[OS command injection] common OS command execution functions and OS command injection utilization examples and range experiments - based on DVWA range

做一篇人人能搞懂的ThreadLocal(源码)

The global chip market may stagnate, and China's chip expansion accelerates to improve its self-sufficiency rate against the trend
随机推荐
简析国内外电商的区别
jvm 参数设置与分析
enable_if
JVM parameter setting and analysis
enable_ if
招标公告:上海市研发公共服务平台管理中心Oracle一体机软硬件维保项目
Type 'image' is not a subtype of type 'imageprovider < object > solution
外部存储器
请求一下子太多了,数据库危
Is there any discount for opening an account now? Is it safe to open an account online?
高效率取幂运算
做一篇人人能搞懂的ThreadLocal(源码)
SFINAE
机械硬盘和ssd固态硬盘的原理对比分析
A brief analysis of the differences between domestic and foreign e-commerce
awk 简明教程
打印输出数(递归方法解决)
[安洵杯 2019]Attack
OpenSSF安全计划:SBOM将驱动软件供应链安全
Gaode map IP positioning 2.0 backup