LeetCode刷题系列(七)Linked List
来源:互联网 发布:审判者极速踢腿宏编程 编辑:程序博客网 时间:2024/06/08 10:40
本篇是有关Linked List的几道相关题型,涉及链表的一些基本的操作和技巧,这些之前的blog也有提到过。
Sort List
题目为把一个链表进行排序,要求时间复杂度为O(nlgn)。链表我们一般无法使用快排,因为它进行随机访问太耗时。回忆之前提到过的Merge Two Sorted List的解法,发现我们将链表一分为二然后再合并就好了,但是这里合并的两个链表都必须是有序的,因此我们需要使用分治法来解决来问题。
private ListNode findMiddle(ListNode head) { ListNode slow = head, fast = head.next; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; } return slow;} private ListNode merge(ListNode head1, ListNode head2) { ListNode dummy = new ListNode(0); ListNode tail = dummy; while (head1 != null && head2 != null) { if (head1.val < head2.val) { tail.next = head1; head1 = head1.next; } else { tail.next = head2; head2 = head2.next; } tail = tail.next; } if (head1 != null) { tail.next = head1; } else { tail.next = head2; } return dummy.next;}public ListNode sortList(ListNode head) { if (head == null || head.next == null) { return head; } ListNode mid = findMiddle(head); ListNode right = sortList(mid.next); mid.next = null; ListNode left = sortList(head); return merge(left, right);}
其中,sortList即为分治法,我们将链表一分为二,然后合并。
Partition List
题目是给定一个目标值和一个链表,将链表中数值小于目标值的节点移到左侧,将数值大于目标值的节点移到右侧(该目标值节点的右侧)。此题目如之前所介绍,由于我们不知道头结点会是哪个元素,因此我们需要设置dummynode作为Head。另外,从题目可以看出我们将链表中的节点按目标值分成两个链表,之后直接接在一起即可。
public ListNode partition(ListNode head, int x) { if (head == null) { return null; } ListNode leftDummy = new ListNode(0); ListNode rightDummy = new ListNode(0); ListNode left = leftDummy, right = rightDummy; while (head != null) { if (head.val < x) { left.next = head; left = head; } else { right.next = head; right = head; } head = head.next; } right.next = null; left.next = rightDummy.next; return leftDummy.next;}
Reorder List
题目:Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do this in-place without altering the nodes’ values. For example, Given {1,2,3,4}, reorder it to {1,4,2,3}.
这道题目的思路是,首先将链表从中间分开(可用之前的findMiddle函数),然后将从中间节点开头的链表倒转(可用之前的reverse函数),最后将他们merge在一起,这个merge区别于之前排序时使用的merge,比他简单很多,仅交替节点相接即可。这里仅给出merge的代码:
private void merge(ListNode head1, ListNode head2) { int index = 0; ListNode dummy = new ListNode(0); while (head1 != null && head2 != null) { if (index % 2 == 0) { dummy.next = head1; head1 = head1.next; } else { dummy.next = head2; head2 = head2.next; } dummy = dummy.next; index ++; } if (head1 != null) { dummy.next = head1; } else { dummy.next = head2; }}
Linked List Cycle
题目为判断一个链表中是否有环。此题可以借鉴之前findMiddle的代码,用一个一次走两步的fast节点和一个一次仅走一步的slow节点。
public Boolean hasCycle(ListNode head) { if (head == null || head.next == null) { return false; } ListNode fast, slow; fast = head.next; slow = head; while (fast != slow) { if(fast==null || fast.next==null) return false; fast = fast.next.next; slow = slow.next; } return true;}
Linked List Cycle II
此题目在Linked List Cycle基础上,要返回环开始的节点。因此,可根据之前代码的基础上做一些修改。根据之前代码分析:如果存在环,fast节点要比slow节点多走一圈,那么再进一步想,slow现在的位置到环开始处的节点的距离其实就是头结点到环开始处的节点的距离。
public ListNode detectCycle(ListNode head) { if (head == null || head.next==null) { return null; } ListNode fast, slow; fast = head.next; slow = head; while (fast != slow) { if(fast==null || fast.next==null) return null; fast = fast.next.next; slow = slow.next; } while (head != slow.next) { head = head.next; slow = slow.next; } return head;}
- LeetCode刷题系列(七)Linked List
- [leetcode刷题系列]Flatten Binary Tree to Linked List
- leetcode系列(72)Reverse Linked List
- leetcode系列(77)Palindrome Linked List
- <leetcode系列> Palindrome Linked List
- <leetcode系列> Linked List Cycle
- leetcode系列(70)Linked List Cycle,Linked List Cycle II
- leetcode系列(75)Delete Node in a Linked List
- leetcode系列(76)Remove Linked List Elements
- LeetCode刷题笔录Linked List Cycle
- leetcode刷题系列--206. Reverse Linked List 递归和非递归 c++实现
- 【Leetcode长征系列】Linked List Cycle
- 【Leetcode长征系列】Linked List Cycle II
- <leetcode系列> Linked List Cycle II
- leetCode刷题归纳-linked list(141. Linked List Cycle&& Add to List 142. Linked List Cycle II)
- [leetcode刷题总结]Reverse Linked List II
- LeetCode刷题笔录Linked List Cycle II
- LeetCode刷题笔录Flatten Binary Tree to Linked List
- 3.3.const关键字和指针的纠缠
- Docker CentOS7 LNMP环境yum方式安装
- openvpn access server 一键搭建脚本
- 上半年遇到的一些service绑定失败的分析
- JavaScript闭包--简介
- LeetCode刷题系列(七)Linked List
- MySQL读写分离原理图
- 无向图连通度(割)
- Html Learning Note from a beginner
- 计蒜客2015 初赛题解及代码
- Python高级特性
- (OK)(OK) running two Android-x86 in VirtualBox, they connect to NS3(MANETs) via "ethernet bridge"
- HTML5学习笔记-基础篇1
- SourceTree 克隆遇到问题 templates not found /Users/mbasaralusrinivasa/workspace...