题目如下:
解题过程如下:
回文结构举例:
回文数字:12521、12321、1221……
回文字符串:“abcba”、“abba”……
并不是所有的循环嵌套的时间复杂度都是O(n^2)
可以用C++写C程序:
C++里可以直接使用ListNode
作为结构体类型名:
思路1:新建一个单链表,保存原来链表的结点,反转新链表,遍历这两个链表比较结点是否相同。
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:bool chkPalindrome(ListNode* A) {//新建一个单链表,保存原链表的结点,反转新链表ListNode* n1, *n2, *n3;n1 = NULL, n2 = A, n3 = n2->next;while (n2){n2->next = n1;n1 = n2;n2 = n3;if (n3){n3 = n3->next;}}//遍历这两个链表,比较这两个链表中的结点数值是否相等while (A && n1){if (A->val == n1->val){A = A->next;n1 = n1->next;}else {return false;}}return true;}
};
思路2:创建一个数组(大小900),遍历原链表将结点中的数值依次存储在数组中,判断数组是否为回文结构。
创建一个数组,有900个空间,空间复杂度:O(900) == O(1)
i
表示存储的结点中数据的个数(数组中有效数据的个数)
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:bool chkPalindrome(ListNode* A) {//新建一个数组(大小900)int arr[900] = { 0 };//遍历单链表,将链表结点中的数值依次存储在数组中ListNode* pcur = A;int i = 0;while (pcur){arr[i++] = pcur->val;pcur = pcur->next;}//判断数组是否是回文结构int left = 0, right = i - 1;while (left < right){if (arr[left] != arr[right]){return false;}left++;right--;}return true;}
};
题干没有“保证链表长度小于等于900”这句话,思路2不适用。
思路3:找到链表的中间结点(快慢指针),中间结点作为新链表的头结点然后反转链表,比较两个链表里的值是否相等。
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:bool chkPalindrome(ListNode* A) {//找到链表的中间结点(快慢指针)ListNode* slow, *fast;slow = fast = A;while (fast && fast->next){slow = slow->next;fast = fast->next->next;}//中间结点作为新链表的头结点,反转新链表ListNode* n1, *n2, *n3;n1 = NULL, n2 = slow, n3 = n2->next;while (n2){n2->next = n1;n1 = n2;n2 = n3;if (n3){n3 = n3->next;}}//比较两个链表中的结点存储的数值ListNode* newHead = n1;ListNode* head = A;while (newHead && head){if (newHead->val != head->val){return false;}head = head->next;newHead = newHead->next;}return true;}
};
思路3代码完善:找链表的中间结点和反转链表可以分别封装成一个函数实现。
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:ListNode* middleNode(ListNode* head){ListNode* slow, *fast;slow = fast = head;while (fast && fast->next){slow = slow->next;fast = fast->next->next;}return slow;}ListNode* reverseList(ListNode* head){if (head == NULL){return NULL;}ListNode* n1, *n2, *n3;n1 = NULL, n2 = head, n3 = n2->next;while (n2){n2->next = n1;n1 = n2;n2 = n3;if (n3){n3 = n3->next;}}return n1;}bool chkPalindrome(ListNode* A) {//1.找到链表的中间结点ListNode* mid = middleNode(A);//2.中间结点作为头结点,反转链表ListNode* right = reverseList(mid);//3.比较两个链表的结点里的值是否相等ListNode* left = A;while (right){if (left->val != right->val){return false;}left = left->next;right = right->next;}return true;}
};