Palindrome Index

傳送門: Palindrome Indexc++

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 Formatthis

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

Output Formatcode

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

bcbc

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

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

Sample Inputrem

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\n", i-1);
38                 break;
39             }
40         }
41     }
42     return 0;
43 }

只是這解法過於暴力,TLE。

下面就要引入這道題給個人最大啓示了:

尋找有助於簡化問題的必要條件

考慮一下上面的單純暴力算法有那些冗餘計算。

首先必須指出一個問題:優化算法的途徑是充分考慮問題的特殊性。

其次要注意到:題目要求的是存在性判別,上面的算法枚舉被刪除字符的位置是無可厚非的。

接着考慮一下使上面的算法達到最壞狀況的數據:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab

在這種狀況下,上述算法必須枚舉到最後一個字符才能肯定答案。

咱們不難發現一個問題

相關文章
相關標籤/搜索