华为OD机考题(HJ32 密码截取)

前言

经过前期的数据结构和算法学习,开始以OD机考题作为练习题,继续加强下熟练程度。有需要的可以同步练习下。

描述

Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

数据范围:字符串长度满足 1≤𝑛≤2500 1≤n≤2500

输入描述:

输入一个字符串(字符串的长度不超过2500)

输出描述:

返回有效密码串的最大长度

示例1

输入:

复制代码
12HHHHA

输出:

复制代码
4

实现原理

根据题干分析,该题是最长回文子串的判断。

1.采用滑动窗口的形式逐步判断滑动窗口内的字符串是否符合对应密码的要求。具体实现见如下。

实现代码

java 复制代码
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        String input = in.nextLine();
        int left = 0;
        int right = input.length();
        int res=0;
        //System.out.println(input.length());
        for (int i = 0; i < input.length(); i++) {
            for(int j=input.length()-1;j>=i+1;j--){   
                int oneStepRes=check(input.substring(i,j+1));
                if(oneStepRes>0){
                    res=Math.max(res,oneStepRes);
                    break;
                }       
            }  
        }
        System.out.println(res);
    }

    public static int check(String str) {
        //System.out.println(str);
        int left = 0;
        int right = str.length() - 1;
        boolean flag=true;;
        while(left<right){
            if(str.charAt(left) == str.charAt(right)){
                //System.out.println("left:"+str.charAt(left));
                left++;
                right--;
                continue;
            }else{
                flag=false;
                break;
            }
        }
        if(flag){
            //System.out.println(str.length());
            return str.length();
        }
        return 0;
    }



}

动态规划法

从上述的算法来看,存在较多的重复判断。大大增加算法执行时间。

java 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        String input = in.nextLine();
        int res=validLen(input);
        System.out.println(res);
        in.close();
    }
    
    public static int validLen(String s) {
        int len = s.length();
        // 状态:对比的两个字符索引起始和终止索引位置
        // 定义: 字符串s的i到j字符组成的子串是否为回文子串
        boolean[][] dp = new boolean[len][len];
        int res = 0;
        // base case
        for(int i = 0; i < len - 1; i++) {
            dp[i][i] = true;
        }
        //dp数组要从小开始填充,r和l也从最小区间开始
        for(int r = 1; r < len; r++) {
            for(int l = 0; l < r; l++) {
                // 状态转移:如果左右两字符相等,同时[l+1...r-1]范围内的字符是回文子串
                // 则 [l...r] 也是回文子串
                if(s.charAt(l) == s.charAt(r) && (r-l <= 2 || dp[l+1][r-1])) {
                    dp[l][r] = true;
                    // 不断更新最大长度
                    res = Math.max(res, r - l + 1);
                } 
            }
        }
        return res;
    }
}

中心扩散法

java 复制代码
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        System.out.println(solution(s));
    }
    
    private static int solution(String s) {
        int res = 0;
        for(int i = 0; i < s.length(); i++) {
            // ABA型
            int len1 = longest(s, i, i);
            // ABBA型
            int len2 = longest(s, i, i + 1);
            res = Math.max(res, len1 > len2 ? len1 : len2);
        }
        return res;
    }
    
    private static int longest(String s, int l, int r) {
        while(l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {
            l--;
            r++;
        }
        return r - l - 1;
    }
}
相关推荐
冷雨夜中漫步6 小时前
Python快速入门(6)——for/if/while语句
开发语言·经验分享·笔记·python
JH30737 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
颜酱7 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
m0_736919108 小时前
C++代码风格检查工具
开发语言·c++·算法
yugi9878388 小时前
基于MATLAB强化学习的单智能体与多智能体路径规划算法
算法·matlab
Coder_Boy_8 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
2501_944934738 小时前
高职大数据技术专业,CDA和Python认证优先考哪个?
大数据·开发语言·python
DuHz8 小时前
超宽带脉冲无线电(Ultra Wideband Impulse Radio, UWB)简介
论文阅读·算法·汽车·信息与通信·信号处理
invicinble8 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
Polaris北极星少女8 小时前
TRSV优化2
算法