【PHP解法==LeetCode链表类型(重排链表类型)】234.回文链表 && 143.重排链表 && 61.旋转链表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010365335/article/details/86750711

目录

234.回文链表

143.重排链表

61.旋转链表


234.回文链表

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

解析:回文即正反序都一样,所以只要找出中间节点,然后翻转后面部分的链表,再一一进行比较

(找到中间节点,为LeetCode876.链表的中间节点题一样)

解法:

1.快慢指针找出中间节点,快指针每次走两个,慢指针走一格

2.翻转后边部分

3.一一比较,得出结果

class Solution {
    function isPalindrome($head) {
        $dummyHead = new ListNode(null);
        $dummyHead->next = $head;
        //快满指针取中间位置
        $centerNode = $doubleNode = $dummyHead;
        while($doubleNode->next){
            $centerNode = $centerNode->next;
            $doubleNode = $doubleNode->next->next;
        }
        //翻转后边部分
        $preNode = null;                //前节点
        $curNode = $centerNode->next;   //后部分的第一个节点
        while ($curNode) {
            $nextNode = $curNode->next;
            $curNode->next = $preNode;
            $preNode = $curNode;
            $curNode = $nextNode;
        }
        //一一比较
        $curNode = $dummyHead->next;
        //遍历结束,$preNode指向反转后,后面部分的第一个节点
        while ($curNode && $preNode) {
            if($curNode->val != $preNode->val){
                return false;
            }
            $curNode = $curNode->next;
            $preNode = $preNode->next;
        }
        return true;
    }
}

143.重排链表

给定一个单链表 LL0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→LnL1→Ln-1→L2→Ln-2→…

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例 1:    给定链表 1->2->3->4, 重新排列为 1->4->2->3.

示例 2:    给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.

解析:解法与234.回文链表类似,区别:这道题不是要比较,而是进行重新连接

解法:

1.快慢指针找出中间节点,快指针每次走两个,慢指针走一格

2.翻转后边部分,区分出两条单链表

3.一一链接,得出结果

class Solution {
    function reorderList($head) {
        $dummyHead = new ListNode(null);
        $dummyHead->next = $head;
        //快慢指针取中间位置
        $centerNode = $doubleNode = $dummyHead;
        while($doubleNode->next){
            $centerNode = $centerNode->next;
            $doubleNode = $doubleNode->next->next;
        }
        //翻转后边部分
        $preNode = null;
        $curNode = $centerNode->next;
        while ($curNode) {
            $nextNode = $curNode->next;
            $curNode->next = $preNode;
            $preNode = $curNode;
            $curNode = $nextNode;
        }
        /**
         * 将前部分的链表封尾,就完成构建两条链表
         * head -> 1 -> 2 -> 3 -> end 
         * head-> 5 -> 4 -> end
         */
        $centerNode->next = null;
        //两两合并,初始化两个链表的头节点
        $curNode = $dummyHead->next;
        $revNode = $preNode;
        while ($revNode) {
            //存下一节点
            $curNextNode = $curNode->next;
            $revNextNode = $revNode->next;

            //交换节点
            $curNode->next = $revNode;
            $revNode->next = $curNextNode;

            //重新定义节点
            $curNode = $curNextNode;
            $revNode = $revNextNode;
        }
        return $dummyHead->next;
    }
}

61.旋转链表

给定一个链表,旋转链表,将链表每个节点向右移动 个位置,其中 是非负数。

示例 1:

输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL

示例 2:

输入: 0->1->2->NULL, k = 4
输出:2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL

解析:从示例不难看出,该旋转可以看成是头尾节点链接,形成循环链表,再去找到倒数第K个节点,断开则得到答案

解法:

1.头尾链接并计算出链表长度$len

2.计算移动长度,$len = $len - ($k%$len) ,因为旋转次数=链表长度时,链表不变

3.旋转链表

class Solution {
    function rotateRight($head, $k) {
        $dummyHead = new ListNode(null);
        $dummyHead->next = $head;
        //1.头尾链接并计算出链表长度
        $curNode = $head;
        $len = 1;
        while ($curNode->next) {        //计算链表长度
            $curNode = $curNode->next;
            $len++;
        }
        $curNode->next = $head;         //循环后curNode指向尾节点,进行头尾链接
        //2.计算移动长度
        $len = $len - ($k%$len);
        //3.旋转链表
        $tailNode = $curNode;           //指向尾节点,也是旋转链表完成后的最后一个节点
        $curNode = $head;               //指向当前的头节点,也是旋转链表完成后的第一个节点
        for($i = 0;$i<$len;++$i){
            $curNode = $curNode->next;
            $tailNode = $tailNode->next;
        }
        $tailNode->next = null;        //对尾指针进行封尾
        return $curNode;               //返回头节点进行遍历即可
    }
}

猜你喜欢

转载自blog.csdn.net/u010365335/article/details/86750711
今日推荐