[LeetCode]409. Longest Palindrome 解题报告

Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.

This is case sensitive, for example "Aa" is not considered a palindrome here.

Note:
Assume the length of given string will not exceed 1,010.

Example:

Input:
"abccccdd"

Output:
7

Explanation:
One longest palindrome that can be built is "dccaccd", whose length is 7.

这个题属于easy难度,确实比较容易。其实这题跟Palindrome没什么关系,分析以后会发现,Palindrome肯定是成对成对出现的,所以,找出所有成对的字母即可,如果剩下单个的字母,那么可以放在最中间,最后的长度加一,否则不加。

具体来说,先把String转换为char[],直接操作数组总是最快的。先从头开始遍历整个字符串,找到和第一个字母一样的字母,计数,当前字母数量/2*2,就当前字母的有效长度。如果统计过的字母,可以作一个标记,比如“*”,这样下次就可以不统计了。接下来统计第二个字母,如果这个字母为*,就不统计了。以此类推,直到最后一个。

另外,需要一个boolean型变量,来记住是否有单独出来的字母,字母数量%2,就知道了,然后将boolean设为true,在返回值的时候判断这个变量是不是true就好了。

尽管对于统计过的字母作了标记,但是这种标记只是为了不重复统计相同的字母,并不会减少遍历的次数,所以这种方法的时间复杂度仍然为O(n^2)

代码如下:

public class Solution {
	public int longestPalindrome(String s) {
		int nLongestLength = 0;
		boolean bAlone = false;
		char[] cArr = s.toCharArray();
		int nIndex = 0;
		while (nIndex < cArr.length) {
			int nCurrentNum = 0;
			char cLast = cArr[nIndex];
			for (int i = 0; i < cArr.length; i++) {
				if (cLast == cArr[i]) {
					nCurrentNum++;
					cArr[i] = '*';
				}
				while (i + 1 < cArr.length && cArr[i + 1] == '*') {
					i++;
				}
			}
			nLongestLength += (nCurrentNum / 2) * 2;
			bAlone = (!bAlone && nCurrentNum % 2 == 1) ? true : bAlone;
			while (nIndex + 1 < cArr.length && cArr[nIndex + 1] == '*') {
				nIndex++;
			}
			nIndex++;
		}
		return bAlone ? nLongestLength + 1 : nLongestLength;
	}
}

接下来,对于数组,我们可以使用LinkedList来处理,使用list.remove来代替“*”的处理,如果统计过了,直接从list里面去掉即可。但是这种方法性能非常差,我个人认为性能瓶颈可能在Linkedlist的构造和操作上。因此,提交代码的时候建议尽量使用数组。
public class Solution {
	public int longestPalindrome(String s) {
		int nLongestLength = 0;
		boolean bAlone = false;
		char[] cArr = s.toCharArray();
		List listChar = new LinkedList<>();
		for (Character character : cArr) {
			listChar.add(character);
		}
		while (listChar.size() > 0) {
			int nCurrentNum = 0;
			char cLast = listChar.get(0);
			for (int i = 0; i < listChar.size(); i++) {
				if (cLast == listChar.get(i)) {
					nCurrentNum++;
					listChar.remove(i);
					i--;
				}
			}
			nLongestLength += (nCurrentNum / 2) * 2;
			bAlone = (!bAlone && nCurrentNum % 2 == 1) ? true : bAlone;
		}
		return bAlone ? nLongestLength + 1 : nLongestLength;
	}
}

第一种方式大约打败了60%,第二种方式打败了0.5%。

你可能感兴趣的:(LeetCode)