判断链表是否为回文链表

import java.util.Stack;

public class pro {
  public static void main(String[] args) {}

  public static class Node { //单链表
    public int value;
    public Node next;

    public Node(int data) { this.value = data; }
  }

  //方法一:使用栈
  public static boolean isPalindrome1(Node head) {
    Stack<Node> stack = new Stack<Node>();
    Node cur = head;      // cur指针赋予当前传入节点
    while (cur != null) { //首节点置尾,每个节点依次压栈
      stack.push(cur);
      cur = cur.next;
    }
    while (head != null) { //依次比较,如果不同则返回false
      if (head.value != stack.pop().value) {
        return false;
      }
      head = head.next;
    }
    return true;
  }

  //方法二:还是使用栈,但是只用一半
  public static boolean isPalindrome2(Node head) {
    if (head == null ||
        head.next == null) { //如果只有单节点或者没有节点都为回文链表
      return true;
    }
    Node right = head.next, cur = head;
    while (cur.next != null && cur.next.next != null) {
      right = right.next;  //慢指针
      cur = cur.next.next; //快指针
    }
    Stack<Node> stack = new Stack<Node>(); //创建以Node为基本单位的栈
    while (right.next != null) { //将慢指针后面的所有节点压栈
      stack.push(right);
      right = right.next;
    }
    while (!stack.isEmpty()) {
      if (head.value != stack.pop().value) {
        return false;
      }
      head = head.next;
    }
    return true;
  }

  //第三种方法:只用常数级别的额外空间
  public static boolean isPalindrome3(Node head) {
    if (head == null || head.next == null)
      return true;
    Node n1 = head, n2 = head;
    while (n2.next != null && n2.next.next != null) {
      n1 = n1.next;      //慢指针走到一半
      n2 = n2.next.next; //快指针走到末尾
    }
    n2 = n1.next;   // n2变成后一半的第一个
    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) {
        res = 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;
  }
}

用栈来判断链表是否回文串是常见的算法问题,通常会先将链表转换成数组或者双向链表,然后利用栈的特性来实现。以下是使用栈的C++方法: 1. 遍历链表:首先,我们需要创建两个指针,一个正向遍历链表(`curr`),另一个反向遍历链表(`reverseCurr`)。初始时,反向指针设为链表的尾部。 2. 双向插入栈:当正向指针不为空时,将正向指针的节点值压入栈,同时移动正向和反向指针。这样可以保证栈顶元素始终包含链表中对应位置的节点。 3. 对比栈顶:当正向指针和反向指针相遇(或其中之一到达链表头)时,如果栈顶元素(正向节点)等于当前反向节点,继续比较下一个节点。如果所有节点都满足这个条件,链表就是回文的;否则不是。 4. 使用栈:C++中,可以使用`std::stack<int>`数据结构来保存节点值,`push()`用于入栈,`top()`获取栈顶元素,`pop()`移除栈顶元素。 ```cpp #include <iostream> #include <stack> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; bool isPalindrome(ListNode* head) { stack<int> s; ListNode* curr = head, *reverseCurr = new ListNode(0); reverseCurr->next = head; while (curr != nullptr && reverseCurr->next != nullptr) { s.push(curr->val); reverseCurr = reverseCurr->next; curr = curr->next; } while (reverseCurr->next != nullptr) { reverseCurr = reverseCurr->next; } while (!s.empty()) { if (s.top() != curr->val) { return false; } s.pop(); curr = curr->next; } return true; } int main() { // 测试代码省略 ListNode* list = ...; // 创建链表 if (isPalindrome(list)) { cout << "The linked list is a palindrome." << endl; } else { cout << "The linked list is not a palindrome." << endl; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值