From 387f9278b102a5b5714a9e23a31a2af49fae51fe Mon Sep 17 00:00:00 2001 From: TripleZ Date: Wed, 10 Oct 2018 13:32:57 +0800 Subject: [PATCH] palindromeList: another implementation O(n) time complexity & O(1) space complexity --- .../palindromeList/LinkedList.hpp | 118 ++++++++++++++++++ .../06_linkedlist/palindromeList/ListNode.hpp | 16 +++ .../palindromeList/palindromeList.cpp | 92 ++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 c-cpp/06_linkedlist/palindromeList/LinkedList.hpp create mode 100644 c-cpp/06_linkedlist/palindromeList/ListNode.hpp create mode 100644 c-cpp/06_linkedlist/palindromeList/palindromeList.cpp diff --git a/c-cpp/06_linkedlist/palindromeList/LinkedList.hpp b/c-cpp/06_linkedlist/palindromeList/LinkedList.hpp new file mode 100644 index 00000000..737e41e8 --- /dev/null +++ b/c-cpp/06_linkedlist/palindromeList/LinkedList.hpp @@ -0,0 +1,118 @@ +/** + * Author: TripleZ + * Date: 2018-10-10 + * Brief: Linked list class. + */ + +#ifndef _LINKEDLIST_HPP_ +#define _LINKEDLIST_HPP_ + +#include +#include "ListNode.hpp" + +class LinkedList { +public: + int size; + int length; + ListNode *head; + LinkedList(); + LinkedList(int size); + ~LinkedList(); + ListNode* FindElem(int elemVal); + bool DeleteElem(ListNode *elem); + bool DeleteLastElem(); + bool InsertElemAtFront(int elemVal); + bool InsertElemAtBack(int elemVal); + void PrintList(); +}; + +LinkedList::LinkedList() { + this -> head = new ListNode(); + this -> head->next = nullptr; + this -> head->val = -1; + this -> size = 10; // default + this -> length = 0; +} + +LinkedList::LinkedList(int size) { + this -> head = new ListNode(); + this -> head->next = nullptr; + this -> head->val = -1; + + this -> size = size; + this -> length = 0; +} + +LinkedList::~LinkedList() { + ListNode *p, *q; + p = this -> head; + while(p -> next != nullptr) { + q = p -> next; + p -> next = p -> next -> next; + delete q; + } + delete head; + this -> head = nullptr; + this -> length = 0; +} + +ListNode* LinkedList::FindElem(int elemVal) { + ListNode *p; + for (p = this -> head; p != nullptr; p = p -> next) { + if (p -> val == elemVal) { + return p; + } + } + return nullptr; +} + +bool LinkedList::DeleteElem(ListNode *elem) { + ListNode *prev, *next; + for (prev = this -> head; prev -> next != elem; prev = prev -> next); + next = elem -> next; + prev -> next = next; + delete elem; + this -> length --; + return true; +} + +bool LinkedList::DeleteLastElem() { + ListNode *prev, *elem; + for (prev = this -> head; prev -> next -> next != nullptr; prev = prev -> next) ; + elem = prev -> next; + prev -> next = nullptr; + delete elem; + this -> length --; + return true; +} + +bool LinkedList::InsertElemAtFront(int elemVal) { + ListNode *newNode = new ListNode(); + newNode -> val = elemVal; + newNode -> next = this -> head -> next; + this -> head -> next = newNode; + this -> length ++; + return true; +} + +bool LinkedList::InsertElemAtBack(int elemVal) { + ListNode *newNode = new ListNode(); + newNode -> val = elemVal; + ListNode *end; + for (end = this -> head; end -> next != nullptr; end = end -> next); + end -> next = newNode; + newNode -> next = nullptr; + this -> length ++; + return true; +} + +void LinkedList::PrintList() { + ListNode *elem; + printf("List: "); + for (elem = this -> head -> next; elem -> next != nullptr; elem = elem -> next) { + printf("%d - ", elem -> val); + } + printf("%d\n", elem -> val); +} + +#endif diff --git a/c-cpp/06_linkedlist/palindromeList/ListNode.hpp b/c-cpp/06_linkedlist/palindromeList/ListNode.hpp new file mode 100644 index 00000000..5b6189b0 --- /dev/null +++ b/c-cpp/06_linkedlist/palindromeList/ListNode.hpp @@ -0,0 +1,16 @@ +/** + * Author: TripleZ + * Date: 2018-10-10 + * Brief: ListNode class. + */ + +#ifndef _LISTNODE_HPP_ +#define _LISTNODE_HPP_ + +class ListNode { +public: + int val; + ListNode *next; +}; + +#endif diff --git a/c-cpp/06_linkedlist/palindromeList/palindromeList.cpp b/c-cpp/06_linkedlist/palindromeList/palindromeList.cpp new file mode 100644 index 00000000..5c3915b8 --- /dev/null +++ b/c-cpp/06_linkedlist/palindromeList/palindromeList.cpp @@ -0,0 +1,92 @@ +/** + * Author: TripleZ + * Date: 2018-10-10 + * Brief: Check a list whether is palindrome. + */ + +#include +#include "LinkedList.hpp" + +bool CheckPalindromeList(LinkedList *list) { + // 使用快慢指针找链表中点 + ListNode *slow, *fast, *mid2; + slow = list -> head; + fast = list -> head; + while (fast -> next != nullptr) { + slow = slow -> next; + fast = fast -> next; + if (fast -> next != nullptr) { + fast = fast -> next; + mid2 = slow -> next; + } else { + mid2 = nullptr; + } + } + + // 从中点向后逆转链表(区分奇偶情况) + ListNode *mid = slow; + ListNode *elem, *prev, *save; + if (mid2 == nullptr) { // odd + elem = mid; + prev = mid -> next; + } else { // even + elem = mid2; + prev = mid2 -> next; + mid2 -> next = nullptr; + } + save = prev -> next; + mid -> next = nullptr; + while (save != nullptr) { + prev -> next = elem; + elem = prev; + prev = save; + save = save -> next; + } + prev -> next = elem; + + ListNode *end = prev; + ListNode *front = list -> head -> next; + + // 从头尾同时遍历比较,检测链表是否为回文 + bool palindrome = true; + while (front != end) { + // printf("%d, %d\n", front -> val, end -> val); + if (front -> val != end -> val) { + palindrome = false; + break; + } + front = front -> next; + end = end -> next; + } + + palindrome ? printf("The list is palindrome~\n") : printf("The list is not palindrome!\n"); + + return palindrome; +} + +int main(int argc, char const *argv[]) { + + int init[] = {1, 2, 3, 2, 1}; + LinkedList *list = new LinkedList(5); + for (int i = 0; i < 5; i++) { + list -> InsertElemAtBack(init[i]); + } + list -> PrintList(); + + CheckPalindromeList(list); // true + + list -> InsertElemAtFront(5); + CheckPalindromeList(list); // false + + + int init2[] = {1, 2, 3, 3, 2, 1}; + LinkedList *list2 = new LinkedList(10); + for (int i = 0; i < 6; i++) list2 -> InsertElemAtBack(init2[i]); + list2 -> PrintList(); + CheckPalindromeList(list2); + + list2 -> InsertElemAtBack(4); + CheckPalindromeList(list2); + + return 0; +}