《程序员面试金典》--判断链表是否为回文链表

题目描述:
请编写一个函数,检查链表是否为回文。给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
测试样例: {1,2,3,2,1}
返回:true
测试样例:{1,2,3,2,3}

返回:false

题目分析:

《方法1》:反转链表

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

《方法2》:栈实现

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

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

《方法3》:递归法

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

程序代码实现:

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};
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;
	}
};







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值