题解 | #牛群编号的回文顺序II#
牛群编号的回文顺序II
https://www.nowcoder.com/practice/e887280579bb4d91934378ea359f632e
考察知识点: 链表、STL
题目分析:
题目中使用的链表不方便进行向前查询,所以可以将链表中的值放入vector数组中,以快速进行随机查询。
回文串有两种情况:
- 奇数回文串。例如
1,2,3,4,3,2,1
- 偶数回文串。例如
1,2,3,4,4,3,2,1
解题时,可以使用中心扩展法,即遍历整个链表,将链表中的每一个节点看作中点,使用left
和right
指针分别向左和向右遍历牛群编号,判断其是否满足回文串的要求,并找到最长的回文串。使用该方法时,要考虑到奇数回文串和偶数回文串的情况
,两种情况下的回文串取最长的一个。
可以先获取回文串头节点start
和尾结点end
在vector数组中的索引位置,当start
是0并且end
是原来链表中的最后一个结点时,说明原链表是一个回文串。否则根据start
和end
从原链表中找到满足要求的子串并返回。
所用编程语言: C++
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param head ListNode类
* @return ListNode类
*/
pair<int, int> expandAroundCenter(vector<int> &cows, int left, int right)
{
int size = cows.size();
while (left >= 0 && right < size && cows[left] == cows[right]) {
left--;
right++;
}
return {++left, --right};
}
ListNode* maxPalindrome(ListNode* head) {
// write code here
ListNode *p = head;
vector<int> cows;
while (p) {
cows.push_back(p->val);
p = p->next;
}
int size = cows.size();
int start = 0, end = 0;
for (int i = 0; i < size; i++) {
auto [left1, right1] = expandAroundCenter(cows, i, i);
auto [left2, right2] = expandAroundCenter(cows, i, i + 1);
if (right1 - left1 > end - start) {
start = left1;
end = right1;
}
if (right2 - left2 > end - start) {
start = left2;
end = right2;
}
}
if (start == 0 && end == size - 1) {
return nullptr;
}
else {
p = head;
ListNode *e = head;
int i, j;
for (i = 0; i < start; i++) p = p->next;
for (j = i, e = p; j < end; j++) e = e->next;
e->next = nullptr;
return p;
}
}
};