解法有两种最基本的方式,空间复杂度O(n)–递归方式,空间复杂度O(1)–找中点、反序后半部分链表、比较即可。
1 递归方式
最核心基础的数据类型是数组,链表。进而组成栈、队、堆、树、图等。
从链表定义来看就注定它具有递归的特点,递归是浓墨重彩的一部分。
void traverse(ListNode *head){
//前序遍历代码--正序
traverse(head->next);
//后序遍历代码--倒序
}
其实递归的学习方法就是手动画下递归树,很显然,代码的相对顺序直接决定遍历方式。
下面就是一个简单的实现方式,这里分析下‘注意"
‘注意: "递归代码不能从表面去看,如注意2,其实这里整个链表已经全部全部入栈,也就是倒序了,一定要结合递归树
之后myLeft只是配合同时移动一步而已。
最后,代码空间复杂度是O(n),结果排在后,用的是系统栈,这里存放的指针,所以数据量大也不会很快爆栈。
/** \brief isPalindrome 回文链表
* \author xxx
* \copyright GNU Public License
* \version 1.0
* \date 2020-1-14
* \remark 递归方式求解--后序遍历也就是倒序
*
* \param[in] head 输入链表
* \return 返回是否是回文链表
*/
ListNode *myLeft = NULL; /**<left和库名重复,所有取了新名字 */
bool traverse(ListNode *right){
if(right == NULL) return true; /**<相当于初始条件,假定初始为真 */
bool res = traverse(right->next); /**<------注意1-----*/
res = (res && right->val == myLeft->val);/**<------注意2-----*/
myLeft = myLeft->next; /**<右移动一个即可 */
return res;
}
bool isPalindrome(ListNode* head) {
myLeft = head; /**<左边指针往右走 */
return traverse(head);
}
2 找中点、反序后半部分链表、比较即可
1 找中点
很简单,相同的路程,一个速度是另外一个的两倍,快的到终点,慢的就在中间;
如果是偶数个,就在中间偏右的位置;
循环的判断条件?你画一个3个长度,4个长度走一遍就知道了哈(奇偶各有一个判断条件);
2 反序后半部分链表
反转的时候需不需要考虑奇数还是偶数,其实不需要,即使是奇数个,反转变成最后一个啊,
换句话说,前面的长度肯定是小于等于后面,若后面的多一个,其实是回文串中间的位置,不用考虑
3 比较即可
由于前面的长度肯定是小于等于后面,所以遍历前面的即可
/** \brief isPalindrome 回文链表
* \author wzk
* \copyright GNU Public License
* \version 1.0
* \date 2020-1-13
*
* \param[in] head 输入链表
* \return 返回是否是回文链表
*/
bool isPalindrome(ListNode* head) {
/**<STEP1 寻找链表的中点,若为奇数则是中间偏右(slow) */
/**<fast指针每次走两步,slow每次走一步 */
ListNode *fast = head;
ListNode *slow = head;
while (fast != NULL && fast->next != NULL) { /**<手动画下元素只有3,4的情况*/
fast = fast->next->next;
slow = slow->next;
}
/**<STEP2 后半部分反转 */
ListNode *secondHalfHead = NULL;
while (slow != NULL) {
ListNode *temp = slow->next; /**<这里要临时转存下p->next,最后又恢复给p */
slow->next = secondHalfHead;
secondHalfHead = slow;
slow = temp;
}
/**<STEP3 比较,如果是奇数,由于slow取得中间偏右,回文中间那个不会考虑哦 */
ListNode *p = head;
ListNode *q = secondHalfHead;
while (p != NULL) {
if(p->val != q->val)
return false;
p = p->next;
q = q->next;
}
return true;
}