`
xitonga
  • 浏览: 585847 次
文章分类
社区版块
存档分类
最新评论

LinkLists 检查一个链表是否为回文 Check if a linked list is palindrome @CareerCup

 
阅读更多

Implement a function to check a linked list is a palindrome

检查一个链表是否为回文


思路:

1 Iterative,利用栈,把链表前半段存入栈,再逐个弹栈和链表后半段比较。注意链表长度为奇数的情况!要跳过中间节点!

2 递归!

定义递归函数为Result rec(LinkedListNode head, int length) 意义为传入链表头结点和链表长度,返回该链表的尾节点的下一个节点

Result是一个Wrapper 类,包含了node和当前是否match的判断

递归的关键是要清楚递归函数的每一个参数的意义是什么,还有返回值的意义是什么!!!

如下图:假设在递归的某一个阶段,要比较前半段的那个1和后半段的那个1是否相等:

根据递归可以得到蓝色部分的返回值Result,包含了一个res.node和match值。res.node的意义就是该子链表的尾节点的下一个节点,即后半段的1!

然后我们可以把head指向的1和res.node指向的1比较。如果相同则设置match为true,并且更新本层递归(红色区域)的返回值为本层子链表的尾节点(1)的下一个节点(0),作为res.node返回。




package LinkLists;

import java.util.Stack;

import CtCILibrary.LinkedListNode;

public class S2_7 {

	// 利用栈,把链表前半段存入栈,再逐个弹栈和链表后半段比较
	public static boolean isPalindrome(LinkedListNode head) {
		LinkedListNode fast = head;
		LinkedListNode slow = head;

		Stack<Integer> stack = new Stack<Integer>();

		while (fast != null && fast.next != null) {
			stack.push(slow.data);
			slow = slow.next;
			fast = fast.next.next;
		}

		if (fast != null) { // 只有当链表长度为奇数时,fast才不会为null
			slow = slow.next; // 这时要跳过中间节点
		}

		while (slow != null) { // 边弹栈边比较
			int top = stack.pop().intValue();
			if (top != slow.data) {
				return false;
			}
			slow = slow.next;
		}
		return true;
	}

	// 递归
	public static boolean isPalindrome2(LinkedListNode head) {
		int size = 0;
		LinkedListNode n = head;
		while (n != null) {
			size++;
			n = n.next;
		}
		Result p = rec(head, size);
		return p.match;
	}

	// 传入链表头结点和链表长度,返回该链表的尾节点的下一个节点
	public static Result rec(LinkedListNode head, int length) {
		if (head == null || length == 0) {	// 空链表,肯定是回文
			return new Result(null, true);
		} else if (length == 1) {		// 只有1个节点,肯定是回文
			return new Result(head.next, true);
		} else if (length == 2) {		// 有两个节点,如果相同则是回文
			return new Result(head.next.next, head.data == head.next.data);
		}
		
		Result res = rec(head.next, length-2);		// 长度缩小2的子链表问题,res存放子问题的结果和子链表尾节点的下一个节点
		if(!res.match || res.node==null) {			// 不match
			return res;
		} else{
			res.match = head.data == res.node.data;		// 比较当前节点和尾节点是否相等
			res.node = res.node.next;							// 更新返回值,即该链表的尾节点的下一个节点
			return res;
		}
	}
	
	static class Result {
		public LinkedListNode node;
		public boolean match;
		public Result(LinkedListNode n, boolean res) {
			node = n;
			match = res;
		}
	}
	
	
	public static void main(String[] args) {
		int length = 10;
		LinkedListNode[] nodes = new LinkedListNode[length];
		for (int i = 0; i < length; i++) {
			nodes[i] = new LinkedListNode(i >= length / 2 ? length - i - 1 : i, null, null);
		}

		for (int i = 0; i < length; i++) {
			if (i < length - 1) {
				nodes[i].setNext(nodes[i + 1]);
			}
			if (i > 0) {
				nodes[i].setPrevious(nodes[i - 1]);
			}
		}
//		 nodes[length - 2].data = 9; // Uncomment to ruin palindrome

		LinkedListNode head = nodes[0];
		System.out.println(head.printForward());
		System.out.println(isPalindrome2(head));
	}

}




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics