[LeetCode] 214. Shortest Palindrome

最短回文串。给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。例子,

Example 1:

Input: "aacecaaa"
Output: "aaacecaaa"

Example 2:

Input: "abcd"
Output: "dcbabcd"

这道题的最优解是马拉车算法,我这里给出two pointer的做法,代码运行速度慢一些。因为是找回文串,所以思路大概还是往two pointer上靠。所以一开始创建两个指针,在input的左右两端。如果两端的char一样,则往中间逼近,直到两个指针相遇,这是最理想的情况。如果一旦发现中间有两端char不一样的情况,则把左指针再放回开头,右指针放回end - 1的位置(舍弃最后一个char)再次比较。

worse case比如这个,aaaaabcaaaaa,因为每次end只挪动一位,所以当两个指针逼近到b和c的时候,end还是需要一步一步往左边移动,效率非常低。所以时间会接近于O(n^2)

时间O(n^2) - worse case

空间O(1)

Java实现

 1 class Solution {
 2     public String shortestPalindrome(String s) {
 3         int i = 0, end = s.length() - 1, j = end;
 4         char chs[] = s.toCharArray();
 5         while (i < j) {
 6             if (chs[i] == chs[j]) {
 7                 i++;
 8                 j--;
 9             } else {
10                 i = 0;
11                 end--;
12                 j = end;
13             }
14         }
15         return new StringBuilder(s.substring(end + 1)).reverse().toString() + s;
16     }
17 }

JavaScript实现

 1 /**
 2  * @param {string} s
 3  * @return {string}
 4  */
 5 var shortestPalindrome = function (s) {
 6     let i = 0;
 7     let j = s.length - 1;
 8     let end = s.length - 1;
 9     while (i < j) {
10         if (s.charAt(i) == s.charAt(j)) {
11             i++;
12             j--;
13         } else {
14             i = 0;
15             end--;
16             j = end;
17         }
18     }
19     return [...s.substring(end + 1)].reverse().join('') + s;
20 };

举个例子

input: abcd

双指针很显然没法逼近,因为一开始的a跟d就不一样,所以a再次跟c比较,跟b比较,都不行。根据代码,此时end在跳出while循环的时候,已经跟i一样,在a的位置了,所以bcd(end + 1)就会成为palindrome的一半,需要复制这个一半的reverse(dcb),再和s拼接在一起(dcb + abcd),组成最短的回文串dcbabcd

猜你喜欢

转载自www.cnblogs.com/aaronliu1991/p/12670940.html