判断链表是否是回文结构-采用堆栈和逆序的不同方式来实现(java)

判断链表是否是回文结构

题目: 给定一个链表的头节点head,请判断链表是否是回文结构。
例子:1-2-1 返回true,12-3-12 返回true, 1-2-3 返回false.

使用堆栈的方式来判断是否是回文结构。

思路,将链表的节点压进栈中,利用栈的先进后出的特点,不断弹出和链表中的节点进行对比,来判断是否是回文结构。

先定义一个链表结构。

  public static class Node{
        public int val;
        public Node next;

        public Node(int val) {
            this.val = val;
        }
    }

上代码:

  public static boolean isPalindrome(Node head){
  		//单节点和null 认为是回文结构。
        if (head == null || head.next == null){
            return true;
        }
        //将节点压进栈中
        Node cur = head;
        Stack<Node> nodes = new Stack<>();
        while (cur != null){
            nodes.add(cur);
            cur = cur.next;
        }
        cur = head;
       //弹出节点去判断。
        while (!nodes.isEmpty()){
            if (nodes.pop().val != cur.val){
                return false;
            }
            cur = cur.next;
        }
        return true;
    }

快慢指针加栈来实现

通过快慢指针,先找出链表的中间节点,把中间节点后面的节点压进栈中,然后只比对一半的节点就可以实现判断。

代码演示:

 public static boolean isPalindrome2(Node head){
        if (head == null || head.next == null){
            return true;
        }
        //奇数长度找到中间节点,偶数节点找到链表的下中点。
        Node right = head.next;
        Node fast = head;
        while (fast.next != null && fast.next.next != null){
            right = right.next;
            fast = fast.next.next;
        }
			//压进栈中
        Stack<Node> nodes = new Stack<>();
        while (right !=  null){
            nodes.add(right);
            right = right.next;
        }
        Node cur = head;
        while (!nodes.isEmpty()){
            if (nodes.pop().val != cur.val){
                return false;
            }
            cur = cur.next;
        }

        return true;
    }

解法三: 取出后半段数字进行翻转。

将后半段的节点逆序,演示:1->2->3->3->2->1, 后半段逆序成:
1->2->3<-3<-2<-1 ,然后拿到头节点和尾节点,循环进行判断,判断完成后,再将链表顺序调整回去。

代码演示

 public static boolean isPalindrome6(Node head) {
        if (head == null || head.next == null) {
            return true;
        }
        Node n1 = head;
        Node n2 = head;
        while (n2.next != null && n2.next.next != null) { // find mid node
            n1 = n1.next; // n1 -> mid
            n2 = n2.next.next; // n2 -> end
        }
        // n1 中点


        n2 = n1.next; // n2 -> right part first node
        n1.next = null; // mid.next -> null
        Node n3 = null;
        while (n2 != null) { // right part convert
            n3 = n2.next; // n3 -> save next node
            n2.next = n1; // next of right node convert
            n1 = n2; // n1 move
            n2 = n3; // n2 move
        }
        n3 = n1; // n3 -> save last node
        n2 = head;// n2 -> left first node
        boolean res = true;
        while (n1 != null && n2 != null) { // check palindrome
            if (n1.val != n2.val) {
                res = false;
                break;
            }
            n1 = n1.next; // left to mid
            n2 = n2.next; // right to mid
        }
        n1 = n3.next;
        n3.next = null;
        while (n1 != null) { // recover list
            n2 = n1.next;
            n1.next = n3;
            n3 = n1;
            n1 = n2;
        }
        return res;
    }

不熟悉快慢指针。可以查看上篇文章。
快慢指针法来确定链表中间位置

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值