码迷,mamicode.com
首页 > 其他好文 > 详细

LinkedList_LeetCode019

时间:2020-01-25 19:36:24      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:mes   null   return   code   引用   内存占用   sys   and   tin   

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

标签:mes   null   return   code   引用   内存占用   sys   and   tin   

原文地址:https://www.cnblogs.com/SsoZhNO-1/p/12233256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!