判断回文链表,回文串

判断回文链表

回文数的特点就是从左往右和从右往左是一样的顺序
判断是不是回文链表就利用这一特点
12321 这就是一组回文数

解决回文链表的思想

  • 将原来的链表拷贝一份并且反转(这样做是为了不改变原有链表),如果原链表是回文链表则新拷贝的链表和原来的链表是一样的,此时只需要同时遍历两个链表然后逐个比较

代码如下:

        // 拷贝链表并且反转
       ListNode temp = head;
       ListNode newNode = null;
       ListNode newTemp = null;
       while(temp!=null){
           newNode = new ListNode(temp.val);
           newNode.next = newTemp;
           newTemp = newNode;
           temp = temp.next;
       }

       // 同时遍历两个链表
       temp = head;
       newTemp = newNode;
       while(temp!=null&&newTemp!=null){
           // 只要出现了不相同的值则原链表不是回文链表
           if(temp.val==newTemp.val){
               temp = temp.next;
               newTemp = newTemp.next;
           }else{
               return false;
           }
       }
       return true;
   }
  • 回文数都是左右对称的,因此可以考虑只反转一半,如果左右两边完全相同则原链表是回文链表

先找到链表的中点确定要反转的部分(如果链表为奇数则反转中点节点之后的节点)如果为偶数则刚好反转一半节点

寻找链表中点:

    // 找到链表的中点 (链表长度为偶数则找后面那个节点))
   public ListNode midPoint(ListNode head){
       ListNode fast = head;
       ListNode slow = head;

       // 链表长度为奇数的时候结束循环的时候fast.next为null
       // 偶数的时候结束循环的时候fast为null
       while(fast!=null&&fast.next!=null){
           // 快慢节点 快的一次走两步 慢的一次一步 
           // 快的走到末尾了之后 慢的刚好在中间
           fast = fast.next.next;
           slow = slow.next;
       }
       
       // 如果为奇数则需要返回中间节点的下一个节点,中间节点不能反转
       if(fast!=null){
           slow = slow.next;
       }
       return slow;
   }

反转找到的中间节点之后的节点:

// 反转slow节点以及之后的节点
    public ListNode reverseM(ListNode head){
        // 前一个节点
        ListNode pre = null;
        // 当前节点
        ListNode cur = head;
        // 下一个待反转节点
        ListNode nex = head;
        while(cur!=null){
            nex = cur.next;
            cur.next = pre;
            pre = cur;
            cur = nex;
        }
        return pre;
    }

调用以上两个函数并执行最终的比较:

    public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
            return true;
        }
        ListNode oldHead = head;
        // 得到反转后那一半头结点
        ListNode newHead = reverseM(midPoint(head));
        // 遍历比较反转部分和未反转部分
        while(newHead!=null){
            // 出现不相等的值 则证明不是回文链表
            if(newHead.val!=oldHead.val){
                return false;
            }
            oldHead = oldHead.next;
            newHead = newHead.next;
        }
        return true;
    }

判断回文字符串

使用两个指针一个从头开始一个从尾部开始,同时开始遍历互相靠近
代码如下:

    public static boolean isPalindrome(String str){
        if(str.length()==0||str.length()==1){
            return true;
        }

        int leftIndex = 0;
        int rightIndex = str.length()-1;

        while (leftIndex<=rightIndex){
            if(str.charAt(leftIndex)!=str.charAt(rightIndex)){
                return false;
            }
            leftIndex++;
            rightIndex--;
        }
        return true;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值