[LeetCode-234] Palindrome Linked List(回文链表、链表中间节点查找)
2015-10-08 21:46
477 查看
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
【分析】
找到链表中点,拆分后,逆转后半个链表,然后两个链表同时顺序遍历一次。
不过唯一需要注意的是,当链表长度为奇数,我们需要先将链表中点往下移动一个节点后在反转半个链表
比如{1->2->3->2->1} 我们找到链表中点3之后需要向下移动一个节点{1->2->3}只需要比较1->2 这两个节点是否相等
时间复杂度O(n),空间复杂度O(1)
代码如下:
完整的代码如下:
Follow up:
Could you do it in O(n) time and O(1) space?
【分析】
找到链表中点,拆分后,逆转后半个链表,然后两个链表同时顺序遍历一次。
不过唯一需要注意的是,当链表长度为奇数,我们需要先将链表中点往下移动一个节点后在反转半个链表
比如{1->2->3->2->1} 我们找到链表中点3之后需要向下移动一个节点{1->2->3}只需要比较1->2 这两个节点是否相等
时间复杂度O(n),空间复杂度O(1)
代码如下:
struct LinkNodeMid { struct ListNode *LastNode; struct ListNode *NodeMid; }; /*无头结点*/ struct ListNode* reverseList(struct ListNode* head) { if((head == NULL) || (head->next==NULL)) //链表为空,或只有一个结点(无需反转),直接返回 return head; struct ListNode *pre = NULL;//前一个 struct ListNode *cur = NULL;//当前 struct ListNode *ne = NULL;//后一个 pre = head; //将前面几个节点的地址依次保存在新定义的结构体指针 cur = head ->next; while(cur) { ne = cur->next; //如果当前节点不为空,则将其指针域赋给ne指针 cur->next = pre; //直接将两个指针的指向反转 pre = cur; //将当前节点赋给pre,将三个指针在链表中的位子都往后移一位 cur = ne; } head->next = NULL;//将原来的第一个节点的指针域赋为空,作为尾节点 head = pre; //将原来的尾节点变成新链表的第一个节点 return head; } struct LinkNodeMid* getLinkNodeMid(struct ListNode* head) { /*at least two nodes*/ struct ListNode* slow = head; struct ListNode* fast = head; struct LinkNodeMid* LinkNodeMidinfo = (struct LinkNodeMid*)malloc(sizeof(struct LinkNodeMid)); /*Fast Linknode move double step one time, slow Linknode move one step, then the slow is the mid head*/ while(fast != NULL && fast->next != NULL) { slow = slow->next; fast = fast->next->next;/*even is NULL,then end the cycle*/ } LinkNodeMidinfo->LastNode = fast; LinkNodeMidinfo->NodeMid = slow; return LinkNodeMidinfo; } bool isPalindrome(struct ListNode* head) { if(!head||!head->next) return true; struct ListNode* phead = head; struct LinkNodeMid* LinkNodeMidinfo= getLinkNodeMid(phead); struct ListNode* pReverseListhead = NULL; /*if LastNode is NULL,then the length LinkNode is odd,otherwise is even*/ if(LinkNodeMidinfo->LastNode) { pReverseListhead = reverseList(LinkNodeMidinfo->NodeMid->next); } else { pReverseListhead = reverseList(LinkNodeMidinfo->NodeMid); } while(phead && pReverseListhead) { if(phead->val != pReverseListhead->val) { free(LinkNodeMidinfo); return false; } phead = phead->next; pReverseListhead = pReverseListhead->next; } free(LinkNodeMidinfo); return true; }
完整的代码如下:
// LeetCode234-Palindrome Linked List.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <stdio.h> #include <stdlib.h> /** * Definition for singly-linked list. **/ struct ListNode { int val; struct ListNode *next; }; /*1.Get LinkNodeMid by NodeMid; 2.LastNode is to distinguish the length LinkNode is odd or even if LastNode is NULL,then the length LinkNode is odd,otherwise is even*/ struct LinkNodeMid { struct ListNode *LastNode; struct ListNode *NodeMid; }; struct ListNode* CreatLink(int aData[],int len) { if(!aData) return NULL; struct ListNode *head = NULL; struct ListNode *p = NULL; struct ListNode *Link= NULL; /*第一个节点*/ head = (struct ListNode *)malloc(sizeof(struct ListNode)); head->val = aData[0]; head->next = NULL; // aData ++; Link = head; /*保存头结点*/ int i = 1; while(i < len) { p = (struct ListNode *)malloc(sizeof(struct ListNode)); p->val = aData[i]; head->next = p; head = p; i ++; } head->next = NULL; return Link; } void printLink(struct ListNode *head) { while(head) { printf("%d",head->val); head = head->next; } printf("\n"); } /*无头结点*/ struct ListNode* reverseList(struct ListNode* head) { if((head == NULL) || (head->next==NULL)) //链表为空,或只有一个结点(无需反转),直接返回 return head; struct ListNode *pre = NULL;//前一个 struct ListNode *cur = NULL;//当前 struct ListNode *ne = NULL;//后一个 pre = head; //将前面几个节点的地址依次保存在新定义的结构体指针 cur = head ->next; while(cur) { ne = cur->next; //如果当前节点不为空,则将其指针域赋给ne指针 cur->next = pre; //直接将两个指针的指向反转 pre = cur; //将当前节点赋给pre,将三个指针在链表中的位子都往后移一位 cur = ne; } head->next = NULL;//将原来的第一个节点的指针域赋为空,作为尾节点 head = pre; //将原来的尾节点变成新链表的第一个节点 return head; } struct LinkNodeMid* getLinkNodeMid(struct ListNode* head) { /*at least two nodes*/ struct ListNode* slow = head; struct ListNode* fast = head; struct LinkNodeMid* LinkNodeMidinfo = (struct LinkNodeMid*)malloc(sizeof(struct LinkNodeMid)); /*Fast Linknode move double step one time, slow Linknode move one step, then the slow is the mid head*/ while(fast != NULL && fast->next != NULL) { slow = slow->next; fast = fast->next->next;/*even is NULL,then end the cycle*/ } LinkNodeMidinfo->LastNode = fast; LinkNodeMidinfo->NodeMid = slow; return LinkNodeMidinfo; } bool isPalindrome(struct ListNode* head) { if(!head||!head->next) return false; struct ListNode* phead = head; struct LinkNodeMid* LinkNodeMidinfo= getLinkNodeMid(phead); struct ListNode* pReverseListhead = NULL; /*if LastNode is NULL,then the length LinkNode is odd,otherwise is even*/ if(LinkNodeMidinfo->LastNode) { pReverseListhead = reverseList(LinkNodeMidinfo->NodeMid->next); } else { pReverseListhead = reverseList(LinkNodeMidinfo->NodeMid); } while(phead && pReverseListhead) { if(phead->val != pReverseListhead->val) { free(LinkNodeMidinfo); return false; } phead = phead->next; pReverseListhead = pReverseListhead->next; } free(LinkNodeMidinfo); return true; } int _tmain(int argc, _TCHAR* argv[]) { int a[] = {1,1,2,1,1}; struct ListNode *head1 = NULL; head1 = CreatLink(a,sizeof(a)/sizeof(int)); //printLink(head1); printf("[%d] %d\n",__LINE__,isPalindrome(head1)); free(head1); getchar(); return 0; }
相关文章推荐
- leetcode 179 Largest Number
- leetcode 24 Swap Nodes in Pairs
- leetcode 2 Add Two Numbers 方法1
- leetcode 2 Add Two Numbers 方法2
- [LeetCode]47 Permutations II
- [LeetCode]65 Valid Number
- [LeetCode]123 Best Time to Buy and Sell Stock III
- [LeetCode] String Reorder Distance Apart
- [LeetCode] Sliding Window Maximum
- [LeetCode] Find the k-th Smallest Element in the Union of Two Sorted Arrays
- [LeetCode] Determine If Two Rectangles Overlap
- [LeetCode] A Distance Maximizing Problem
- leetcode_linearList
- leetcode_linearList02
- 021-Merge Two Sorted Lists(合并两个排好序的单链表);leetcode
- LeetCode[Day 1] Two Sum 题解
- LeetCode[Day 2] Median of Two Sorted Arrays 题解
- LeetCode[Day 3] Longest Substring Without... 题解
- LeetCode [Day 4] Add Two Numbers 题解
- LeetCode [Day 5] Longest Palindromic Substring 题解