【字符串】B025_驗證迴文字符串 II(暴力 | 雙指針)

一、題目描述

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

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

二、題解

方法一:暴力(超時)

  • 對於每一個位置 i 的字符我們都將其刪除,然後 check 是否是迴文串。

* 數據太大: s 的長度最大爲 50000,N2N^2 的複雜度也就是運行 50000250000^2 = 250000250000 次。

public boolean validPalindrome(String s) {
    int N = s.length();
    StringBuilder sb = new StringBuilder(s);

    for (int i = 0; i < N; i++) {
        StringBuilder t = new StringBuilder(sb);
        t.deleteCharAt(i);
        if (check(t.toString())) {
            return true;
        }
    }
    return false;
}
public boolean check(String s){
    int i = 0; int j = s.length()-1;
    while(i < j){
        if(s.charAt(i) != s.charAt(j)){
            return false;
        }
        i++;
        j--;
    }
    return true;
}

複雜度分析

  • 時間複雜度:O(N2)O(N^2)
  • 空間複雜度:O(n)O(n)

方法二:雙指針

我們只想通過刪除一次字符,再驗證剩下的字符能不能組成迴文串。我們習慣用雙指針判斷迴文串。我們可以這樣去想:假如給定一個序列 s[l], s[l+1] ,..., s[r]

  • 如果 s[l] = s[r],則需要再判斷 s[l+1], s[l+1] ,..., s[r-1] 是否是迴文,直到 l > r 爲止。
  • 如果 s[l] != s[r],證明我可以刪除 s[l]s[r] 其中之一來驗證刪除之後的串是否是迴文。我們將驗證這兩個序列:
    • s[l+1], s[l+1] ,..., s[r]
    • s[l], s[l+1] ,..., s[r-1]
public boolean validPalindrome(String s) {
    int l = 0, r = s.length()-1;
    while (l < r) {
        if (s.charAt(l) != s.charAt(r)) {
            return check(s, l, r-1) || check(s, l+1, r);
        }
        l++; r--;
    }
    return true;
}
public boolean check(String s, int i, int j){
    while(i < j){
        if(s.charAt(i) != s.charAt(j)){
            return false;
        }
        i++; j--;
    }
    return true;
}

複雜度分析

  • 時間複雜度:O(n)O(n)
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章