链表算法面试题---返回链表的中间节点

题目描述

给定一个非空链表的头节点,从该链表的中间节点开始返回。如果中间节点有两个,则返回第二个中间节点。

示例1:

1—>2—>3—>4—>5—>null,中间节点为3,所以返回3—>4—>5—>null。

示例2:

1—>2—>3—>4—>5—>6—>null,中间节点为3、4,根据要求返回第二个中间节点,所以返回4—>5—>6—>null

解题思路

题目本身比较简单,可以借助其他有下标的数据结构来完成,也可以通过先遍历一次求出链表的长度,再遍历一次求出结果。

解法1:

借助有下标的数据结构

    /**
     * 借助数组
     * 因为链表的问题就在与不能通过下标定位到某个节点,所以我们可以借助数组来完成,ArrayList本质就是一个动态数组
     *
     * @param head
     * @return
     */
    public ListNode middleNode(ListNode head) {
    
    
        List<ListNode> nodeList = new ArrayList<>();
        while (head != null) {
    
    
            nodeList.add(head);
            head = head.next;
        }
        return nodeList.get(nodeList.size() / 2);
    }

解法2:

借助栈实现,同数组道理一样

    public ListNode middleNode(ListNode head) {
    
    
    	Stack<ListNode> stack = new Stack<>();
        ListNode c = head;
        //先把所有节点依次入栈
        while (c != null) {
    
    
            stack.push(c);
            c = c.next;
        }
        int size = stack.size();
        int mid = size / 2;
        ListNode res = null;
        //依次从栈中弹出
        for (int i = 0; i < mid; i++) {
    
    
            res = stack.pop();
        }
        //如果是节点的长度是偶数,则直接返回,如果是奇数,则要多弹一个。
        if ((size & 1) == 0) {
    
    
            return res;
        }
        return stack.pop();
    }

解法3:

不借助额外空间,两次遍历

    /**
     * O(1)的空间复杂度实现
     * 数组的方式,需要额外的开辟一个与节点大小一样的空间,那么我们也可以采取遍历两次的方式,省去额外的空间代价
     *
     * @param head
     * @return
     */
    public ListNode middleNode(ListNode head) {
    
    
        ListNode res = head;
        int size = 0;
        while (head != null) {
    
    
            size++;
            head = head.next;
        }

        int index = 0;
        while (index < (size / 2)) {
    
    
            res = res.next;
            index++;
        }

        return res;
    }

解法4:

快慢指针

    /**
     * 快慢指针
     * 慢指针每次走一步,快指针每次走两步,因此快指针走完时,慢指针刚好走了一半,即是我们想要的结果
     *  
     * @param head
     * @return
     */
    public ListNode middleNode(ListNode head) {
    
    
        ListNode slowNode = head;
        ListNode fastNode = head;
        while (fastNode != null && fastNode.next != null) {
    
    
            slowNode = slowNode.next;
            fastNode = fastNode.next.next;
        }
        return slowNode;
    }

猜你喜欢

转载自blog.csdn.net/CSDN_WYL2016/article/details/115010149
今日推荐