LinkedList专题2

原创 2018年04月15日 09:38:50

203 Remove Linked List Elements

思路:考虑1 : 可能有多个节点符合;考虑2:命中节点是head;考虑3:命中节点是尾节点;考虑4:命中节点是中间的普通节点。
学习1:在linkedList 运用递归的思路还是很常见的,我还没有形成习惯。不断缩小问题规模。

    public ListNode removeElementsV2(ListNode head, int val) {
        if(head==null) return null;
        head.next = removeElementsV2(head.next,val);
        if(head.val == val){
            head = head.next;
        }
        return head;
    }

学习2:因为第一版有head节点的特殊处理,可以采取的措施是:加一个假的head或者是dummy节点。代码漂亮多了。

 public ListNode removeElementsV3(ListNode head, int val) {
        ListNode dummy  = new ListNode(-1);
        dummy .next = head;
        ListNode node = head;
        ListNode preNode = dummy ;
        while(node!=null){
            if(node.val==val){
                preNode.next = node.next;
            }else{
                preNode = node;
            }
            node = node.next;
        }
        return dummy .next;
    }

代码

160 Intersection of Two Linked Lists

思路:两个链表相交的起点。方法一:暴力搜索。listA的每个节点与listB的每个节点比较。时间复杂度O(m*n)。方法二:将listA的每个节点放入map中,遍历listB的每个节点与map比较。时间复杂度O(n),空间复杂度O(n)。这两个都不符合要求。
学习:难点是能够观察到:如果listA和listB有交集,那么从交集点开始之后所有的node是相等的,那么长度也是相同的。所以如果有长度差异,一定是在列表的前端。正如demo中所示。可以分别计算两个列表的长度lenA,lenB。长的列表先移动|lenA-lenB|步;之后两个指针一起移动直到所指节点相同。
代码

19 Remove Nth Node From End of List

思路:从尾部开始计算,删除第n个节点。
如果是从头部开始计算,删除第n个节点就比较好处理了。那就把问题转换一下。从尾部开始的第n个节点=从头部开始的第几个节点。
经过画图举例知道 应该是从头部开始第(len-n+1)节点,len是list长度。
假设要删除的节点nodeA ,应该是nodeA的上一个节点.next = nodeA.next。需要处理nodeA的上一个节点不存在的情况,这里加入一个dummy节点。
思路2:使用两个指针first、second。first先走n+1个节点(因为有dummy节点),然后second再走。当first到达队尾的时候,second距离队尾还有n个节点。
学习网页
代码

23 Merge k Sorted Lists

合并k个已经排序好的列表。这个题目有多种解决思路。参考文章
思路1:把所有数据放在一个List,然后排序list。最后再创建ListNode。时间复杂度O(NlogN),N是所有节点的总数。所有数据放入List需要O(n);排序需要O(NlogN),创建节点需要O(N)。空间复杂度O(N)。
思路2:每次比较k个头节点,选择最小的节点。然后继续比较头节点。时间复杂度:O(kN)。k是数组长度,N是节点总数。每次比较需要比较k-1次,有N次比较。
思路3:对思路2的改进。每次把头结点的值放入优先队列中,取得最小值。时间复杂度:(O(Nlogk))。插入和弹出优先队列需要耗时O(logk),获得最小值耗时O(1)。
思路4:把k个队列合并问题转为2个队列合并问题。可以第0个和第1个合并得到result;result再继续和第2个、第3个队列合并。时间复杂度:O(kN)。N是两个list的长度。k个队列需要合并k-1次。
思路5:对思路4的改进。使用分治法(Divide and conquer)。合并0,1队列得到0队列;合并2,3队列得到2队列….;第二层 合并0,2队列得到0队列,合并4,6队列得到4队列;第三层合并0,4队列得到0队列…..一直到结束。时间复杂度:O(Nlogk)。N是两个队列的节点总数。因为会合并logk次。
代码

25 Reverse Nodes in k-Group

思路:将整个列表分成几个长度为k的子链表;对每一个子链表反转。长度不为k的子链表保持不动。
思路1:找到每一个子链表开始、结束下标,然后调用 92 Reverse Linked List II
这样会有一些重复的跳过m个节点的操作。可以进一步优化。从head开始数,数够了k步就从head开始反转长度为k的子链表;接着再从当前节点开始数。够k个就反转。不够就退出。
学习:自己反转的代码写的有点凌乱。再次学习了递归思想。
这里写图片描述
如果要反转链表1->2->3->4->5中1到3的部分得到:3->2->1->4->5。左侧从左向右是一种思路,右侧从右向左也是一种方法。

    public ListNode reverseKGroupV2(ListNode head, int k) {
        ListNode currentNode = head;
        int count =0;
        while(currentNode!=null && count!=k){
            count++;
            currentNode = currentNode.next;
        }
        if(count == k ){
            currentNode = reverseKGroupV2(currentNode,k);
            while(count>0){
                ListNode tmp = head.next;
                head.next = currentNode;
                currentNode = head;
                head = tmp;
                count--;
            }
            head = currentNode;
        }
        return head;
    }

代码

61 Rotate List

思路:因为k可能大于len(链表长度)。所以1 计算列表长度;2 k=k % len;3 将指针移动到len-k的位置,这个位置是开始rotate节点的上一个节点。4 反转。
代码

82 Remove Duplicates from Sorted List II

思路:留下链表中没有重复出现的元素。比较简单。直观地解决就可以。
代码

86 Partition List

思路:用两个指针smallHead,biggerHead分别指向小于x的节点列表和大于等于x的节点列表。最后将两个列表合并返回。
代码

143 Reorder List

思路:1 找到一半节点;2 反转第二部分链表;3合并两个链表。重要的是代码怎么写。
代码

147 Insertion Sort List

思路:处理位置i,从0到i-1是已经排序好的。我写代码的时候还是受数组排序的思维影响比较重。在学习代码中,别人把排序好的作为一个list处理。相对来说要比较好。
代码

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

Python全栈工程师-第2周

-
  • 1970年01月01日 08:00

matlab linkedlist

 The link Lulu suggested in the comments is probably the choice I would make if I were wanting to im...
  • anjen
  • anjen
  • 2009-11-27 10:42:00
  • 987

请使用LinkedList来模拟一个队列(先进先出的特性): 1) 拥有放入对象的方法void put(Object o) 2)取出对象的方法Object get() 3)判断队列当中是否为空的方法b

import java.util.LinkedList; import java.util.List; public class Linkeds { List l; //构造方法 ...
  • two2123427
  • two2123427
  • 2015-08-19 22:29:41
  • 1998

[kuangbin带你飞]专题二-搜索进阶-B-Eight II

ACM模版描述 题解这道题和 Eight 相似,不过终止状态不唯一了,但是我们可以总结为9种状态,每种状态的核心差别是 X 的位置,所以我们需要打九个表,那么问题来了,怎么才能通过给定的终止(或初始...
  • f_zyj
  • f_zyj
  • 2017-04-06 01:45:32
  • 317

ACM第二专题—搜索总结

概述:搜索分为广度优先搜索(BFS)和深度优先搜索(DFS)两类,前者用队列实现,后者用递归实现,后者用于列举所有可能情况,前者用于求最短路径。可以用二分搜索和三分搜索解决一些比较简单的搜索问题。 ...
  • Mr_Ma_ACM
  • Mr_Ma_ACM
  • 2016-04-23 22:26:39
  • 181

java源码分析之集合框架 ArrayList和LinkedList的区别05

List概括 先来回顾一下List在Collection中的的框架图: 从图中我们可以看出: 1. List是一个接口,它继承与Collection接口,代表有序...
  • wangnanwlw
  • wangnanwlw
  • 2016-08-17 13:35:07
  • 672

[kuangbin带你飞]专题二 搜索进阶 A - Eight

A - Eight Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Statu...
  • ZZ_AC
  • ZZ_AC
  • 2015-11-17 16:21:33
  • 662

Vector,ArrayList,LinkedList的特点和区别

1.Vector简介及特点 1、Vector是内部是以动态数组的形式来存储数据的。 2、Vector具有数组所具有的特性、通过索引支持随机访问、所以通过随机访问Vector中的元素效率非常高、但是执...
  • m0_38110132
  • m0_38110132
  • 2017-07-11 15:37:00
  • 935

ArrayList和LinkedList剖析

简介java集合中最顶层的接口为Connection接口,其中有两个接口实现了Connection接口,分别为Set接口和List接口。Set接口表现为无序,不能重复;List接口表现为有序,可重复。...
  • ExcellentYuXiao
  • ExcellentYuXiao
  • 2016-07-04 10:33:18
  • 2921

Java进阶(四十六)简述ArrayList、Vector与LinkedList的异同点

简述ArrayList、Vector与LinkedList的异同点  Collection类的继承图如下:   从图中可以看出,LinkedList与ArrayList、ArrayDeque这三者都...
  • sunhuaqiang1
  • sunhuaqiang1
  • 2016-10-08 20:27:20
  • 44271
收藏助手
不良信息举报
您举报文章:LinkedList专题2
举报原因:
原因补充:

(最多只允许输入30个字)