zoukankan      html  css  js  c++  java
  • Palindrome Index

    传送门: Palindrome Index

    Problem Statement

    You are given a string of lower case letters. Your task is to figure out the index of the character on whose removal it will make the string a palindrome. There will always be a valid solution. 

    In case the string is already a palindrome, then -1 is also a valid answer along with possible indices.

    Input Format

    The first line contains T, i.e. the number of test cases.
    T lines follow, each containing a string.

    Output Format

    Print the position (0 index) of the letter by removing which the string turns into a palindrome. For a string, such as

    bcbc
    

    we can remove b at index 0 or c at index 3. Both answers are accepted.

    Constraints 
    1T20 
    1 length of string 100005 
    All characters are Latin lower case indexed.

    Sample Input

    3
    aaab
    baa
    aaa
    

    Sample Output

    3
    0
    -1
    

    Explanation

    In the given input, T = 3,

    • For input aaab, we can see that removing b from the string makes the string a palindrome, hence the position 3.
    • For input baa, removing b from the string makes the string palindrome, hence the position 0.
    • As the string aaa is already a palindrome, you can output 0, 1 or 2 as removal of any of the characters still maintains the palindrome property. Or you can print -1 as this is already a palindrome.

    读题时需注意:

    题目中先说 “There will always be a valid solution. ”,然后才说“In case the string is already a palindrome, then -1 is also a valid answer along with possible indices.”。注意体会这句话,我们首先应注意到,即使输入的字符串S是个回文串,也可以删除某个字母使其仍为回文串。如果|S|为奇数,则删除中间那个字母,结果串仍为回文串。如果|S|为偶数则删除中间两个相等字符中的任一个,结果串也回文。

    完全暴力的解法:

    枚举要删除的字母,检查结果串是否回文。复杂度O(N^2)。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAX_N=1e5+10;
     4 char s[MAX_N];
     5 int len;
     6 int opp(int j, int x){
     7     if(x==0){
     8         return len+1-j;
     9     }
    10     if(j<x){
    11         return len-j<x? len-j: len-j+1;
    12     }
    13     else{
    14         return len+2-j;
    15     }
    16 }
    17 bool ok(int x){
    18     int tmp=x?(len-1)>>1:len>>1;
    19     for(int i=0, j=1; i<tmp; i++, j++){
    20         if(j==x){
    21             j++;
    22         }
    23         if(s[j]!=s[opp(j, x)]){
    24             return false;
    25         }
    26     }
    27     return true;
    28 }
    29 int main(){
    30     int T;
    31     scanf("%d", &T);
    32     while(T--){
    33         scanf("%s", s+1);
    34         len=strlen(s+1);
    35         for(int i=0; i<=len; i++){
    36             if(ok(i)){
    37                 printf("%d
    ", i-1);
    38                 break;
    39             }
    40         }
    41     }
    42     return 0;
    43 }

    只是这解法过于暴力,TLE。

    下面就要引入这道题给我的最大启示了:

    寻找有助于简化问题的必要条件

    考虑一下上面的单纯暴力算法有那些冗余计算。

    首先必须指出一个问题:优化算法的途径是充分考虑问题的特殊性。

    其次要注意到:题目要求的是存在性判别,上面的算法枚举被删除字符的位置是无可厚非的。

    接着考虑一下使上面的算法达到最坏情况的数据:

    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab

    在这种情况下,上述算法必须枚举到最后一个字符才能确定答案。

    我们不难发现一个问题

     

     

  • 相关阅读:
    Windows下React Native环境配置
    数据处理函数$.grep,$.map,$.makeArray,sort
    gulp的安装与使用
    模块化管理ajax
    Windows操作系统下ionic开发环境搭建
    css平行四边形与菱形变换
    JavaScript数组排序总结
    JavaScript数组去重总结
    vue之修饰符
    深拷贝、浅拷贝
  • 原文地址:https://www.cnblogs.com/Patt/p/4467609.html
Copyright © 2011-2022 走看看