链表常考点
最近一口气刷完了Leetcode上链表专栏下的所有题。有好几题非常有意思,记录一下:
感觉链表的题,大部分都是考察细心的题。你定义好的遍历指针,一定要细心的检查当它遍历时,它的子节点正确赋值,同时要非常注意链表指针非空的情况。
寻找链表的倒数第K个,或者类似的题目。类似的比如:输出链表的后一半。
要求:时间复杂度限制O(n), 空间复杂度是O(1) 解题思路:开辟两个指针p,q. 开始时俩个指针都指向头结点。然后p往后走,q不走。当P走了k步时,q再走。当p走到链表末尾事,q就是倒数第k个了。 代码:
class Solution {
public ListNode middleNode(ListNode head,int k) {
int i=0;
ListNode p,q;
p = head;
q = head;
while(i<k){
if(p!=null){
p = p.next;
i++;
}else{
return null;
}
}
while(p!=null){
p = p.next;
q = q.next;
}
return q;
}
}
判断链表是否是回文链表
(回文链表:链表的值从左往右,从右往左都是一样的) 要求:时间复杂度O(n) ,空间O(1) 解题思路: 首先找到链表的中间,将链表从中间分为俩个链表。 然后反转俩个链表中的一个。最后进行依次对比。
判断链表是否有环,以及输出环的入口
判断有环解题思路:p,q两个指针指向头结点。然后p每次往前走一步,q走俩步,如果再次相遇则有环。
输出环入口解题思路:先运行判断有环的程序。这时,p,q相遇在环中的某个结点。这个结点不一定是入口。 接下来 p=相遇结点,q= 头结点。然后他们每次都走一步,再次相遇就是环入口结点。 具体证明参考:https://blog.csdn.net/xyzxiaoxiong/article/details/78761940 PS:我当时采取的是一个很暴力的方法。因为没有规定空间复杂度,所以我直接 开辟了一个HashSet的数组。每次遍历时,将当前节点加入hashSet中,第一个出现重复的元素即 是环入口。
给链表排序
题目:用O(N*logN)的时间复杂度给链表排序 解题思路:先将链表分为左右俩部分,形成俩个链表。然后对这俩个链表使用归并排序。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
ListNode slow,fast,head1,head2;
if(head==null || head.next==null) return head;
slow = head;
fast = slow;
while(fast!=null && fast.next!=null && fast.next.next!=null){
slow = slow.next;
fast = fast.next.next;
}
fast = slow;
slow = slow.next;
fast.next = null;
head1 = sortList(head);
head2 = sortList(slow);
head = MergeSort(head1,head2);
return head;
}
public ListNode MergeSort(ListNode head1,ListNode head2) {
if(head1==null) return head2;
if(head2==null) return head1;
ListNode head,p,q,cur;
if(head1.val < head2.val){
head = head1;
head1 = head1.next;
}else{
head = head2;
head2 = head2.next;
}
p = head1;
q = head2;
cur = head;
while(p!=null && q!=null){
if(p.val<q.val){
cur.next = p;
cur = cur.next;
p = p.next;
}else{
cur.next = q;
cur = cur.next;
q = q.next;
}
}
while(p!=null){
cur.next = p;
cur = cur.next;
p = p.next;
}
while(q!=null){
cur.next = q;
cur = cur.next;
q = q.next;
}
return head;
}
}
待添加。。。