美文网首页
对称子字符串

对称子字符串

作者: asdfgjsrgdf | 来源:发表于2019-11-19 18:46 被阅读0次

问题描述

       Given a string ‘str’ of digits, find length of the longest substring of ‘str’, such that the length of the substring is 2k digits and sum of left k digits is equal to the sum of right k digits.

输入

       输入第一行是测试用例的个数,后面每一行表示一个数字组成的字符串,例如:"123123"

输出

       输出找到的满足要求的最长子串的长度。例如,给定的例子长度应该是 6。每行对应一个用例的结果。

示例输入

1
1538023

示例输出

4

1.递归解法

       (1)若输入的数字字符串长度length为0或1,则结果为0
       (2)若输入的数字字符串长度length为偶数:
              a. 若前length/2位之和等于后length/2之和===>返回结果length
              b. 若前length/2位之和不等于后length/2之和:===>寻找长度为length-2的子字符串:



       (3)若输入的数字字符串长度length为奇数===>寻找长度为length-1的子字符串:



       代码:
import java.util.Scanner;

public class SymSubstr {
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int casesnum = sc.nextInt();
        sc.nextLine();
        while(casesnum>0){
            String temp = sc.nextLine();
            int[] input = new int[temp.length()];
            for(int i=0;i<input.length;i++){
                input[i] = Integer.parseInt(temp.charAt(i)+"");
            }
            int result = find(input);
            System.out.println(result);
            casesnum --;
        }
    }

    public static int find(int[] input){
        if(input.length==0)
            return 0;
        if(input.length%2 == 0){
            int sum1 = 0;
            int sum2 = 0;
            for(int i=0;i<input.length/2;i++){
                sum1 += input[i];
            }
            for(int i=input.length/2;i<input.length;i++){
                sum2 += input[i];
            }
            if(sum1 == sum2)
                return input.length;
            else{
                int[] new1 = new int[input.length-2];
                int[] new2 = new int[input.length-2];
                int[] new3 = new int[input.length-2];
                for(int i=0;i<input.length-2;i++){
                    new1[i] = input[i];
                }
                for(int i=2;i<input.length;i++){
                    new2[i-2] = input[i];
                }
                for(int i=1;i<input.length-1;i++){
                    new3[i-1] = input[i];
                }
                return Math.max(Math.max(find(new1),find(new2)),find(new3));
            }
        }
        else{
            int[] new1 = new int[input.length-1];
            int[] new2 = new int[input.length-1];
            for(int i=0;i<input.length-1;i++){
                new1[i] = input[i];
            }
            for(int i=1;i<input.length;i++){
                new2[i-1] = input[i];
            }
            return Math.max(find(new1),find(new2));
        }
    }
}

2.动态规划

       上述递归解法存在大量重复计算,会超时。使用动态规划求解:
(1)构建DP[i],长度为length,初始化全为0。i表示关注的字符串长度-1(-1方便编程)
(2)由于字串长度必为偶数,则DP[i]=DP[i-1],i-1为奇数(即偶数位与上一奇数位相同)
(3)对于DP[j],j为偶数,其取值范围为DP[i-1]~i+1(上限为字符串长度:i+1,下限为上一轮结果):
       a.整个字符串是否满足条件,满足则返回字符串长度:L=i+1,否则观察长度为L=L-2的子串是否满足
       b.对于每个L<i+1,只需观察两种情况是否满足:



       输入为1538023时构建DP的例子:



       代码(将调用find改为调用DP):
import java.util.Scanner;

public class SymSubstr {
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int casesnum = sc.nextInt();
        sc.nextLine();
        while(casesnum>0){
            String temp = sc.nextLine();
            int[] input = new int[temp.length()];
            for(int i=0;i<input.length;i++){
                input[i] = Integer.parseInt(temp.charAt(i)+"");
            }
            int result = DP(input);
            System.out.println(result);
            casesnum --;
        }
    }
    public static int DP(int[] input){
        int[] dp = new int[input.length];
        for(int i=0;i<dp.length;i++)
            dp[i] = 0;
        for(int i=1;i<input.length;i++){
            if(i%2 == 0)
                dp[i] = dp[i-1];
            else{
                //判断整个字符串是否满足
                int sum1 = 0;
                int sum2 = 0;
                for(int j=0;j<=i/2;j++)
                    sum1 += input[j];
                for(int j=i/2+1;j<=i;j++)
                    sum2 += input[j];
                if (sum1 == sum2)
                    dp[i] = i+1;
                else{
                    //不满足时,若上一轮的结果是整个字符串的长度,则可以不用计算。因为i-1是此时的下限
                    if(dp[i-1] == i-1)
                        dp[i] = i-1;
                    else{
                        for (int j=i-1;j>dp[i-2];j-=2){
                            //从i-1开始,按照长度递减判断是否存在子字符串
                            //sum3,sum4用于判断情况1,sum5,sum6用于判断情况2
                            int sum3 = 0;
                            int sum4 = 0;
                            int sum5 = 0;
                            int sum6 = 0;
                            //情况1
                            for(int k=i-j+1;k<i-j+1+j/2;k++)
                                sum3 += input[k];
                            for(int k=i-j+1+j/2;k<i+1;k++)
                                sum4 += input[k];
                            //情况2
                            for(int k=i-j;k<i-j+j/2;k++)
                                sum5 += input[k];
                            for(int k=i-j+j/2;k<i;k++)
                                sum6 += input[k];
                            if(sum3 == sum4 || sum5 == sum6) {
                                dp[i] = j;
                                break;
                            }
                        }
                        //若未能在到达下限之前找到答案,则答案为下限
                        if(dp[i] == 0)
                            dp[i] = dp[i-2];
                    }
                }
            }
        }
        return dp[input.length-1];
    }
}

相关文章

  • 对称子字符串

    Description Given a string ‘str’ of digits, find length o...

  • 对称子字符串

    问题描述 Given a string ‘str’ of digits, find length of the l...

  • 两个指针遍历

    1,有一个很常见的问题叫子字符串,相关的问题有LCS(最长公共子字符串),还有最长对称子字符串问题。我们先不讨论算...

  • 最长回文子串

    子串:小于等于原字符串长度由原字符串中任意个连续字符组成的子序列 回文:关于中间字符对称的文法,即“aba”(单...

  • 最长对称子字符串(2)

    解法一在 http://www.jianshu.com/p/d23c6b0e02e2中已经写了,这个方法复杂度太高...

  • pyton判断一个字符串是否是对称字符串

    可以先思考几分钟 判断一个字符串是否是对称字符串, 例如"abc"不是对称字符串,"aba"、"abba"、 "a...

  • L1_008最长对称子串

    对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定"Is PAT&TAP symmetric?",最长对...

  • 输入一个字符串s,我们可以删除字符串s中的任意字符,让剩下的字符

    输入一个字符串s,我们可以删除字符串s中的任意字符,让剩下的字符串形成一个对称字符串,且该字符串为最长对称字符串。...

  • HJ85 最长回文子串

    描述给定一个仅包含小写字母的字符串,求它的最长回文子串的长度。所谓回文串,指左右对称的字符串。所谓子串,指一个字符...

  • 回文子串

    给出一个字符串,取该字符串的一部分即为子串,回文子串就是指该子串正着读,倒着读都是一样的(也就是对称的),例如:a...

网友评论

      本文标题:对称子字符串

      本文链接:https://www.haomeiwen.com/subject/zrdpjqtx.html