首页 > 编程语言 > 详细

算法面试3---链表

时间:2019-09-16 11:28:08      阅读:83      评论:0      收藏:0      [点我收藏+]

1 链表反转

例1:LeetCode 206。本题虽然简单但却是众多公司的面试问题。反转前后的图示如下:

技术分享图片

 在反转的过程中主要是依据指针之间的移动,如下图所示:

技术分享图片

技术分享图片

class Solution {

    public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        while (head != null) {
            //1 每次修改前先把head.next备份否则head修改后找不到head.next
            ListNode nextTemp = head.next; 
            //2 修改head.next temp用来保存的是上次头节点的信息
            head.next = prev;
            //3 temp进行更新保存此次头节点的信息
            prev = head;
            //4 继续进行遍历
            head = nextTemp;
        }    
        //返回新链表的头结点
        return prev;        
    }
        
}

//递归版本的实现
class Solution {
    
    public ListNode reverseList(ListNode head) {
        //递归的终止条件
        if (head == null || head.next == null) return head;
        //递归处理的操作是从最后一个元素开始的
        ListNode p = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return p;
    }
}

与此类似的有题目:LeetCode:92

注: 对于链表操作的一些基础问题:LeetCode 83、86、328、2、445

2 设立链表的虚拟的头结点

 例1:LeetCode 203。对于删除一个节点其图示如下,设待删除的节点为3。

技术分享图片

技术分享图片

 在上面的删除逻辑中对于最后一个元素也是成立的,因为最后一个元素的下一个为NULL。但问题在于第一个元素不成立,因为cur需要指在待删除节点的前一个节点。

class Solution {

    public ListNode removeElements(ListNode head, int val) {
        //1 先处理头部要删除的元素。对于头结点要特殊处理,有可能传入的是空链表因此要判断一下,也有可能下一个头结点仍然为空因此需要进行while循环
        while(head != null && head.val == val){
            ListNode delNode = head;
            head = head.next;
            delNode.next = null;
        }
        //2 处理中间要删除的元素,有可能在上一步操作中已经把链表删除完了,因此在这一步应该判断一下链表是否为空了
        if (head == null) {
            return head;
        }
        //此时head肯定不是要删除的节点了
        ListNode prev = head;
        //找到要删除节点的前一个节点,这也正是前面为什么要头结点特殊处理一下的原因,头结点前面无节点了
        while (prev.next != null) {
            if (prev.next.val == val) {
                ListNode delNode = prev.next;
                prev.next = delNode.next;
                delNode.next = null;
            }else {
                //用prev进行遍历链表
                prev = prev.next;
            }
        }
        //返回删除后的链表
        return head;
    }
}

上面的代码是没有设立虚拟头节点的情况,我们完全可以自己设立一个虚拟的头结点:

class Solution {

    public ListNode removeElements(ListNode head, int val) {
        // 定义一个虚拟的头结点,其值为多少并不重要
        ListNode dummyHead = new ListNode(0);
        // 让定义的虚拟头结点在链表的首部
        dummyHead.next = head;

        ListNode prev = dummyHead;
        //找到要删除节点的前一个节点,首元素的前面是虚拟头结点
        while (prev.next != null) {
            if (prev.next.val == val) {
                ListNode delNode = prev.next;
                prev.next = delNode.next;
                delNode.next = null;
            }else {
                //用prev进行遍历链表
                prev = prev.next;
            }
        }
        //返回删除后的链表
        return dummyHead.next;
    }
}

 与此类似题目有:LeetCode 82、21。

 3 链表进阶

例1:LeetCode 24。采用下图分析,我们需要把2指向1,1指向3,但是1是首元素在遍历的时候用prev即前一个节点肯定是不行的,因此这里还需要堆首元素特殊处理或者是设立一个虚拟的头节点。

 技术分享图片

 

 

技术分享图片

 

因为需要交换所以要定义两个指针分别指向需要交换的两个元素,因为还有指向下一个元素,所以需要定义另外一个节点指向交换后需要指向的元素。

 

 技术分享图片

 

步骤顺序为:把2指向1,然后1指向next,然后p指向2,交换图如下:

技术分享图片

 技术分享图片

 交换完后需要对这些指针进行移动,重复上面的算法即可,在移动时是先把p移动到node1处,然后这些指针以p为基准进行定位的。

技术分享图片

class Solution {

    public ListNode swapPairs(ListNode head) {
        // 先设置好虚拟头结点
        ListNode dummyHead = new ListNode(0);
        dummyHead.next = head;

        ListNode prev = dummyHead;
        // 当结点不为空时才进行交换
        while (prev.next != null && prev.next.next != null){
            // node1根据prev定位,
            ListNode node1 = prev.next;
            ListNode node2 = node1.next;
            ListNode next = node2.next;
            // 进行交换
            node2.next = node1;
            node1.next = next;
            prev.next = node2;
            //移动prev
            prev = node1;
        }
        return dummyHead.next;
    }
}

 在这道题目中也可以不用设置next指针,但这样优化性能提升并不是很明显,可能在代码理解上也会有点困难,因此建议在链表中一开始可以把所有用到的节点都单独保存下来。与此类题目有:25、147、148。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

0

算法面试3---链表

原文:https://www.cnblogs.com/youngao/p/11525932.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!