1. 程式人生 > >680. Valid Palindrome II【easy】

680. Valid Palindrome II【easy】

遞歸 bsp user sta temp code pla lean 我們

680. Valid Palindrome II【easy】

Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.

Example 1:

Input: "aba"
Output: True

Example 2:

Input: "abca"
Output: True
Explanation: You could delete the character ‘c‘.

Note:

  1. The string will only contain lowercase characters a-z. The maximum length of the string is 50000.

錯誤解法:

 1 class Solution {
 2 public:
 3     bool validPalindrome(string s) {
 4         int start = 0;
 5         int end = s.length() - 1;
 6         int flag = false;
 7         
 8         while (start <= end) {
 9             if (s[start] == s[end]) {
10                 ++start;
11 --end; 12 } 13 else { 14 if (!flag) { 15 flag = true; 16 17 if (s[start + 1] == s[end]) { 18 ++start; 19 } else if (s[start] == s[end - 1
]) { 20 --end; 21 } else { 22 return false; 23 } 24 } 25 else { 26 return false; 27 } 28 } 29 } 30 31 return true; 32 33 } 34 };

沒有通過以下測試用例:

"aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga"

考察代碼邏輯,發現一開始我們命中了

s[start + 1] == s[end]

這個邏輯,"aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga",並且設置了標誌位,這就坑了,下次發現不相等的情況,就直接返回false了。

其實我們本意是要命中下面的邏輯

s[start] == s[end - 1]

"aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga",並且設置了標誌位,這樣就可以滿足測試用例。

就是說每次我們用

s[start + 1] == s[end]

s[start] == s[end - 1]

其實是一種“或”的關系,所以我們要一判斷就判斷到底,比如下面的解法一。

解法一:

 1 class Solution {
 2     public boolean validPalindrome(String s)
 3     {
 4         int left = 0, right = s.length() - 1;
 5 
 6         while (left < right)
 7         {
 8             if (s.charAt(left) == s.charAt(right))
 9             {
10                 left++; right--;
11             }
12             else
13             {
14                 //remove right
15                 int templeft = left, tempright = right - 1;
16 
17                 while (templeft < tempright)
18                 {
19                     if (s.charAt(templeft) != s.charAt(tempright)) break;
20                     templeft++; tempright--;
21 
22                     if (templeft >= tempright) return true;
23                 }
24 
25                 //remove left
26                 left++;
27 
28                 while (left < right)
29                 {
30                     if (s.charAt(left) != s.charAt(right)) return false;
31                     left++; right--;
32                 }
33             }
34         }
35         return true;
36     }
37 }

參考@yashar 的代碼。

解法二:

 1 class Solution {
 2     public boolean validPalindrome(String s) 
 3     {
 4         return validPalindrome(s, 0, s.length() - 1, false);
 5     }
 6     
 7     private boolean validPalindrome(String s, int left, int right, Boolean mismatch)
 8     {
 9         if (right < left) return true;
10 
11         if (s.charAt(left) != s.charAt(right))
12         {
13             if (mismatch == true)
14                 return false;
15 
16             return validPalindrome(s, left, right - 1, true) || validPalindrome(s, left + 1, right, true);
17         }
18         else
19         {
20             return validPalindrome(s, left + 1, right - 1, mismatch);
21         }
22     }
23 }

遞歸,參考@yashar 的代碼。

解法三:

 1 class Solution {
 2 public:
 3     bool validPalindrome(string s) {
 4         return valid(s, 0, s.length() - 1, 1);
 5     }
 6 
 7 private:
 8     bool valid(string& s, int i, int j, int d) { // d: num of chars you can delete at most
 9         if (i >= j) return true;
10         if (s[i] == s[j])
11             return valid(s, i + 1, j - 1, d);
12         else
13             return d > 0 && (valid(s, i + 1, j, d - 1) || valid(s, i, j - 1, d - 1));
14     }
15 };

遞歸,參考@alexander 的代碼。

680. Valid Palindrome II【easy】