判断一个链表是否为回文结构

判断一个链表是否为回文结构

题目:

给定一个链表的头节点head,请判断该链表是否为回文结构。
例如:1->2->1,true.
1->2->2->1,true.
15->6->15,true.
1->2->3,false.

借用辅助数组:

通过一个栈,先遍历一遍链表,将所有元素入栈,之后再遍历链表,并且和出栈的元素一一进行比较。其实没有必要将所有元素都入栈,只需要将后一半的元素入栈即可,通过双指针,快指针一次走两步,慢指针一次走一步,这样快指针走到终点时,慢指针就到了中点位置,这时候将元素全部入栈,然后比较。

这种方法推荐在笔试时写,因为方法简单,通过率高,但是不建议面试的时候写,这种方法空间复杂度不好。

//需要n的辅助空间
public static boolean isPalindrome1(Node head)
{
	Stack<Node> stack = new Stack<Node>();
	Node cur = head;
	while(cur!=null)//第一遍遍历,全部入栈
	{
		stack.push(cur);
		cur = cur.next;
	}
	while(head!=null)//第二遍比较
	{
		if(head.value!=stack.pop().value)
		{
			return false;
		}
	}
	return true;
}
//需要n/2的辅助空间
public static boolean isPalindrome2(Node head)
{
	if(head==null || head.next==null)
		return true;
	Node right = head.next;
	Node cur = head;
	while(cur.next!=null && cur.next.next!=null)
	{
		right = right.next;
		cur = cur.next.next;
	}
	Stack<Node> stack = new Stack<Node>();
	while(right!=null)
	{
		stack.push(right);
		right = right.next;
	}
	while(!stack.isEmpty())
	{
		if(head.value!=stack.pop().value)
			return false;
		head = head.next;
	}
	return true;
}
不用辅助数组:

双指针,快指针一次走两步,慢指针一次走一步,快指针走完,慢指针走到中点。然后将中点开始后面节点逆序,比较完之后再将还原该链表。

例如:1->2->3->2->1,慢指针会到达3处,然后右半部分逆序,将3的next指向null,将后面2的next指向3,将1的next指向2,得到1->2->3<-2<-1,一个节点从head开始遍历,一个节点从尾节点开始遍历,比较,一直到中点位置停,若相同,则为true,否则为false。

public static boolean isPalindrome1(Node head)
{
	if(head==null || head.next==null)
		return true;
	Node n1 = head;
	Node n2 = head;
	while(n2.next!=null && n2.next.next!=null)
	{
		//这个函数可以保证当N为奇数时,n1指向中点的位置,n2指向end
		//当n为偶数时,n1指向前一个中点,比如1221,指向第一个2,这样才能正确逆序后面元素
		n1 = n1.next;
		n2 = n2.next.next;
	}
	n2 = n1.next;
	n1.next = null;
	Node n3 = null;
	while(n2!=null)//实现后半部分逆序,可以画图来观察
	{
		n3 = n2.next;
		n2.next = n1;
		n1 = n2;
		n2 = n3;
	}
	n3 = n1;
	n2 = head;
	boolean res = true;
	while(n1!=null && n2!=null)
	{
		if(n1.value!=n2.value)
		{
			return false;
			break;
		}
		n1 = n1.next;
		n2 = n2.next;
	}
	n1 = n3.next;
	n3.next = null;
	while(n1!=null)//重新恢复链表
	{
		n2 = n1.next;
		n1.next = n3;
		n3 = n1;
		n1 = n2;
	}
	return res;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值