python回文链表_回文链表

30

推荐

思路:利用快慢指针,找到中间

查看全部

编辑于 2015-08-18 20:51:02

回复(22)

40

public class Palindrome {

public boolean isPalindrome(ListNode pHead){

ListNode fast = pHead;

ListNode slow = pHead;

Stack stack = new Stack();

/**

* 将链表的前半部分元素装入栈中,当快速runner

*(移动的速度是慢速runner的两倍)

* 到底链表尾部时,则慢速runner已经处于链表中间位置

*/

while(fast != null && fast.next != null){

stack.push(slow.val);

slow = slow.next;

fast = fast.next.next;

}

//当链表为奇数个时,跳过中间元素

if (fast != null) {

slow = slow.next;

}

while(slow != null){

//如果两者不相同,则该链表不是回文串

if (stack.pop() != slow.val) {

return false;

}

slow = slow.next;

}

return true;

}

}

发表于 2015-10-02 17:12:23

回复(12)

19

题目分析:

《方法1》:反转链表

可以将原始链表反转,判断反转以后的链表与原始链表是否完全一致,如果一致便返回true,如果不一致则返回false。反转链表需要额外的存储空间,不是特别优秀的方法。

《方法2》:栈实现

我们可以想到从中间节点向两侧开始比较,如果全部相同,则返回true,否则返回false,因为无法获得一个节点的前一个节点,这个时候我们可以想到用栈实现,先将链表前半部分的元素分别压入堆栈,然后在遍历后半部分元素的时候同时和栈顶元素进行比较,如果全部相等则返回true,否则返回false。

特别注意:因为我们不知道链表的的长度,可以通过快慢指针(一个指针每次移动两个,一个指针每次移动一个)来找到中间元素,这样整体只需要遍历链表一次,所需要的栈空间缩小为方法1的一半。

《方法3》:递归法

递归方法分为尾部递归和首部递归,还有中间递归,一般的尾部递归都可以用循环来实现,对于我们这道题目,递归的时候无法比较第一个元素和最后一个元素,即使知道最后一个元素,也无法获得最后一个元素的前一个元素。所以我们选择首部递归,先递归直到中间的元素,然后比较中间的元素,把比较结果返回,同时保存后半部分下一个要比较的元素(用引用传递可以,用二级指针也可以),递归返回后,如果是true,则继续比较,如果是false,则直接返回false。

《程序员面试金典》程序详解:

递归代码实现:

class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

// write code here

ListNode *tail=pHead;

int length=0;

while(tail)

{

++length;

tail=tail->next;

}

return isPalindrome1(pHead,&tail,length);

}

bool isPalindrome1(ListNode* pHead,ListNode **tail,int length)

{

if(pHead==NULL||length==0)

return true;

if(length==1)

{

*tail=pHead->next;

return true;

}

if(length==2)

{

*tail=pHead->next->next;

return pHead->val==pHead->next->val;

}

bool sign=isPalindrome1(pHead->next,tail,length-2);

if(sign==false)

return false;

ListNode* tail1=*tail;

*tail=tail1->next;

return pHead->val==tail1->val;

}

};

发表于 2015-09-24 19:34:45

回复(2)

11

采用递归的方式,将p定义成static:

每次传入一个新的链表,让p指向链表首节点。

通过递归,pHead从后往前,p从前往后,同时比较。

class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

// write code here

if(pHead==NULL)

return true;

static ListNode* p=NULL;

if(p==NULL) p=pHead;

if(isPalindrome(pHead->next)&&(p->val==pHead->val))

{

p=p->next;

return true;

}

p=NULL;

return false;

}

};

编辑于 2015-09-29 15:55:30

回复(2)

9

/*用数组方式进行添加的,不过数组扩容速度慢(数组最快3n),其他用户的快慢指针是一种办法,

虽然复杂度O(n),但是快慢指针更快(2n)*/

public class Palindrome {

public boolean isPalindrome(ListNode pHead) {

// write code here

ArrayList list = new ArrayList();

if(pHead == null){

return false;

}

ListNode node = pHead;

while(node != null){

list.add(node.val);

node = node.next;

}

int N = list.size();

for(int i = 0;i < N/2; i++){

if(list.get(i) != list.get(N-i-1)){

return false;

}

}

return true;

}

}

发表于 2015-08-31 17:04:18

回复(0)

6

//将链表的后半部分翻转,然后从开头和中间处分别遍历

bool isPalindrome(ListNode* pHead) {

if(pHead == NULL || pHead->next == NULL) return true;

//翻转后半部分链表

ListNode* fast = pHead, *slow = pHead;

while(fast->next != NULL){

fast = fast->next;

if(fast->next != NULL){

fast = fast->next;

slow = slow->next;

}

}

while(slow->next != fast){

ListNode* tmp = slow->next;

slow->next = tmp->next;

tmp->next = fast->next;

fast->next = tmp;

}

//分别从中间和后半部分开始遍历

while(fast != NULL){

if(fast->val != pHead->val)

return false;

fast = fast->next;

pHead = pHead->next;

}

return true;

}

发表于 2017-08-18 15:29:08

回复(0)

10

PYthon solution,easy to understand class Palindrome:

def isPalindrome(self, pHead):

# write code here

arr=[]

while pHead:

arr.append(pHead.val)

pHead=pHead.next

return arr==arr[::-1]

发表于 2017-10-01 20:24:51

回复(2)

3

import java.util.*;

/*

public class ListNode {

int val;

ListNode next = null;

ListNode(int val) {

this.val = val;

}

}*/

public class Palindrome {

public boolean isPalindrome(ListNode pHead) {

// write code here

String str = "";

String str2 = "";

while(pHead!=null){

str = str+String.valueOf(pHead.val);

str2 = String.valueOf(pHead.val)+str2;

pHead = pHead.next;

}

if(str.equals(str2)){

return true;

}else{

return false;

}

}

}

发表于 2016-09-29 15:20:08

回复(2)

2

用一个vector存储,然后从两端遍历并比较

class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

vector seq;

while (pHead) {

seq.push_back(pHead->val);

pHead = pHead->next;

}

for (int i=0; i

int j = seq.size() - i - 1;

if (seq.at(i) != seq.at(j)) { return false; }

}

return true;

}

};

运行时间:4ms

占用内存:612k

发表于 2018-12-24 15:07:02

回复(0)

2

import java.util.*;

/*

public class ListNode {

int val;

ListNode next = null;

ListNode(int val) {

this.val = val;

}

}*/

public class Palindrome {

public boolean isPalindrome(ListNode pHead) {

// write code here

Stack stack = new Stack();

Queue queue = new LinkedList();

int flag = 0;

while(pHead != null){

stack.push(pHead.val);

queue.add(pHead.val);

pHead = pHead.next;

}

while(!stack.isEmpty()){

if(stack.peek() != queue.peek()){

return false;

}

stack.pop();

queue.poll();

}

return true;

}

} 使用栈和队列实现功能

发表于 2018-08-28 20:59:45

回复(0)

2

不使用额外空间,反转后半部分链表,然后一个指针指向链表头,一个指针指向链表中间,

比较值是否相等,不相等就返回false。 class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

// write code here

int count=0;

ListNode* p=pHead;

while(p!=NULL){

p=p->next;

count++;

}

count=count%2==0?count/2:(count/2+1);

p=pHead;

for(int i=0;i

p=p->next;

}

ListNode* pre=NULL;

while(p!=NULL){

ListNode* temp=p->next;

p->next=pre;

pre=p;

p=temp;

}

ListNode* m=pHead;

while(pre!=NULL&&m!=NULL){

if(pre->val!=m->val)

return false;

pre=pre->next;

m=m->next;

}

return true;

}

};

发表于 2018-02-11 21:37:40

回复(0)

2

import java.util.*;

/*

public class ListNode {

int val;

ListNode next = null;

ListNode(int val) {

this.val = val;

}

}*/

public class Palindrome {

public boolean isPalindrome(ListNode pHead) {

// write code here

// 快慢指针找到链表中间位置节点

// 将链表前半部入栈,然后在遍历后半部分时,将元素逐一弹出,进行比较

// 注意处理链表的奇偶,如果为奇,跳过中间节点

ListNode fast = pHead;

ListNode slow = pHead;

Stack stack = new Stack();

while(fast != null && fast.next != null){

stack.push(slow.val);

slow = slow.next;

fast = fast.next.next;

}

if (fast != null) {

slow = slow.next;

}

while(slow != null){

if (stack.pop() != slow.val) {

return false;

}

slow = slow.next;

}

return true;

}

}

发表于 2017-05-30 16:00:32

回复(0)

2

import java.util.*;

//两点关键:快慢指针可以找到中间点,如果快指针不为空,则为奇数个,慢指针此时指向中间点,否则无中间点

//单向链表指针不能往回走,所以通过将前半节打入栈中的方式完成(栈的特性 后进先出)

public class Palindrome {

public boolean isPalindrome(ListNode pHead) {

ListNode slow =pHead;

ListNode fast =pHead;

Stack stack =new Stack();

while(fast!=null&&fast.next!=null ){//找到中间点,并将前半节打入栈中

stack.push(slow.val);

slow =slow.next;

fast =fast.next.next;

}

if(fast!=null){

slow =slow.next;

}

while(slow.next!=null){//指针从中间点开始每下移一个,就与栈中取出的值对比

if(slow.val !=stack.pop()){

return false;

}

slow =slow.next;

}

return true;

}

}

发表于 2017-05-17 10:24:44

回复(1)

2

根据参数链表,以头插法方式建立一个反向的新链表,然后循环比对,C++代码如下

bool isPalindrome(ListNode* pHead) {

// write code here

if (pHead == nullptr)

return false;

ListNode * p = pHead;

ListNode * q ;

ListNode * reverse = new ListNode(0);

reverse->next = nullptr;

while (p != nullptr){

q = new ListNode(p->val);

q->next = reverse->next;

reverse->next = q;

p = p->next;

}

p = pHead;

q = reverse->next;

while (p != nullptr && q != nullptr){

if (p->val != q->val)

return false;

p = p->next;

q = q->next;

}

return true;

}

发表于 2017-05-14 21:39:18

回复(0)

2

思路:

利用一个快指针,慢指针。慢指针每次走一步,快指针每次走两步。把慢指针走过的结点入栈

比较栈中结点跟慢指针剩余为走过的结点(特别注意链表长度是奇数还是偶数,如果是奇数,慢指针应该跳过中间结点再进行比较)

# -*- coding:utf-8 -*-

# class ListNode:

# def __init__(self, x):

# self.val = x

# self.next = None

class Palindrome:

def isPalindrome(self, pHead):

if not pHead or not pHead.next:

return False

stack = []

slow = pHead

fast = pHead.next

stack.append(slow.val)

while True:

# 链表是偶数长度

if not fast.next:

mid = slow.next

break

elif fast.next and not fast.next.next:

mid = slow.next.next

break

slow = slow.next

fast = fast.next.next

stack.append(slow.val)

while stack and mid:

top = stack.pop()

if top != mid.val:

return False

mid = mid.next

return True

发表于 2016-08-02 10:53:45

回复(0)

1

class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

// write code here

vector a;

while(pHead)

{

a.push_back(pHead->val);

pHead=pHead->next;

}

for(int i=0;i

{

if(a[i]!=a[a.size()-1-i])

return false;

}

return true;

}

}; 可以把链表的值传入数组,利用数组进行判断链表是否为回文链表

发表于 2020-03-04 12:37:54

回复(0)

1

/*

struct ListNode {

int val;

struct ListNode *next;

ListNode(int x) : val(x), next(NULL) {}

};*/

class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

// write code here

if (pHead == NULL || pHead->next == NULL) return true;

ListNode* slow = pHead;

ListNode* fast = pHead;

while (fast->next && fast->next->next)

{

slow = slow->next;

fast = fast->next->next;

}

fast = slow->next;

stack stk;

while (fast)

{

stk.push(fast->val);

fast = fast->next;

}

slow = pHead;

while (!stk.empty())

{

if (stk.top() != slow->val) return false;

stk.pop();

slow = slow->next;

}

return true;

}

};

发表于 2019-10-12 23:25:45

回复(0)

1

//不需要那么复杂,直接转换为字符串,直接判断就可以了

class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

if(pHead==nullptr||pHead->next==nullptr)

return true;

string str="";

while(pHead!=nullptr)

{

str+=to_string(pHead->val);

pHead=pHead->next;

}

return str==string(str.rbegin(),str.rend());

}

};

发表于 2019-05-02 15:54:03

回复(0)

1

快慢指针+反转慢链一把梭.

用了快慢指针就强迫症不想用栈. class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

if(!pHead) return true;

ListNode* slow = pHead;

ListNode* fast = slow;

ListNode *tmp = nullptr;

ListNode *last = nullptr;

while (slow && fast && fast->next) {

fast = fast->next->next;

tmp = slow;

slow = slow->next;

tmp->next = last;

last = tmp;

}

if (fast) slow = slow->next;

while(slow && last) {

if(slow->val != last->val) return false;

slow = slow->next;

last = last->next;

}

return true;

}

};

编辑于 2019-02-27 23:15:36

回复(0)

1

利用另一个指针,移到最后,进行对比,再删掉最后一个节点。

class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

// write code here

if(pHead==NULL)return true;

while(pHead!=NULL){

ListNode*pTail=pHead;

if((pTail->next)==NULL)return true;

while((pTail->next->next)!=NULL)pTail=pTail->next;

if((pTail->next->val)!=(pHead->val))return false;

pTail->next=NULL;

pHead=pHead->next;

}

return true;

}

};

发表于 2018-10-30 19:33:26

回复(0)

1

思路:快慢指针 + stack

注意:需要考虑链表的奇偶情况

/* struct ListNode {

int val;

struct ListNode *next;

ListNode(int x) : val(x), next(NULL) {}

};*/

class Palindrome {

public:

bool isPalindrome(ListNode* pHead) {

// write code here

if (NULL == pHead) {

return false;

}

ListNode *faster = pHead;

ListNode *later = pHead;

stack staInt;

while (NULL != faster->next && NULL != faster->next->next) {

staInt.push(later->val);

later = later->next;

faster = faster->next->next;

}

if (NULL != faster->next) {

staInt.push(later->val);

}

later = later->next;

while (!staInt.empty()) {

if (later->val != staInt.top()) {

return false;

}

later = later->next;

staInt.pop();

}

return true;

}

};

发表于 2018-04-25 23:04:24

回复(0)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值