LinkedList_LeetCode019

Posted SsoZh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LinkedList_LeetCode019相关的知识,希望对你有一定的参考价值。

019题:

第一种方法:暴力解,借鉴002创建一个新的ListNode存储答案,先遍历原ListNode获得他的长度并把他放入map,然后读取map并创建出答案来。

其中创建的这个节点的第一位置其实是一个哑节点(dummy node)。用于简化某些极端情况!
    public static ListNode Ssozh_removeNthFromEnd(ListNode head, int n){
//        ListNode.pprint(head);
        Map<Integer,Integer> map = new HashMap<>();
        ListNode tmp = head;
        int cnt = 0;
        for(;;){
            if (tmp.next != null) {
                map.put(cnt,tmp.val);
                tmp=tmp.next;
                cnt++;
            } else {
                map.put(cnt,tmp.val);
//                System.out.println(head.val);
                break;
            }
        }
//        System.out.println(cnt);
        int j = 0;
        ListNode ans = new ListNode(0); // this one will be remove
        ListNode node = ans ;
        for(;;){
            if(j == cnt + 1) break;
            if(j == cnt + 1 - n) {
                j++;
                continue;
            }
            node.next  = new ListNode(map.get(j));
            node = node.next;
            j++;
            System.out.println("j="+j);
        }
        return ans.next;
    }

这种解法的内存占用大,用时慢。对于内存占用大,可以把创建一个新的ans链表改为在原链表上更改的方法。

方法二:依然是暴力解,但是对方法一进行了改进,将创建一个ListNode改为在head上直接改。

//        ListNode.pprint(head);
        ListNode tmp = head;
        int cnt = 0; // len of head and 0 is start number.
        for(;;){
            if (tmp.next != null) {
                tmp=tmp.next;
                cnt++;
            } else {
                break;
            }
        }
        if(n == cnt+1) return head.next; // if n == len ?
        int j = 0;
        ListNode node = head; // in fact this var 'node' could be replace with var 'tmp' and could be turn into dummy. 
        for(;;){
                if(j == cnt +1- n){
                node.next = node.next.next;
                break;
                }
                node = node.next;
                j++;
                }
        return head;

这里需要注意的是,上面无论是tmp,node都是引用,而ans其实是一个深拷贝的操作。这里面是没有浅拷贝的!
上面两种方法都是用了两次遍历,第三种方法比第二种方法快只用了一次遍历,但实质上这三种方法都是O(L)的时间复杂度。

第三种方法:双指针法,先一个指针走n步,然后第二个指针和第一个一次走到头。

    public static ListNode removeNthFromEnd(ListNode head, int n){
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode first = dummy;
        ListNode second = dummy;
        for(int i=0;i<n+1;i++){
            first = first.next; // move n times
        }
        while(first.next!=null){
            first =first.next;
            second = second.next;
        }
        second.next = second.next.next;
        return dummy.next;
    }

以上就是LeetCode019的三种解法,其中与链表相关的还有LeetCode002,与双指针相关的还有011MaxArea。后面会把这些相关的都一起写一下。

以上是关于LinkedList_LeetCode019的主要内容,如果未能解决你的问题,请参考以下文章

团体程序设计天梯赛 L3-019. 代码排版(测试数据+不同方法)

免费下载全套最新019IDEA视频教程+教学资料+学习课件+源代码+软件开发工具

团体程序设计天梯赛L3-019 代码编排(23分)

019Java中定义字符

Qt&Vtk-019-GPURenderDemo

L1-019. 谁先倒