• 【力扣】19. 删除链表的倒数第 N 个结点


    给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

    进阶:你能尝试使用一趟扫描实现吗?

    示例 1:


    输入:head = [1,2,3,4,5], n = 2
    输出:[1,2,3,5]
    示例 2:

    输入:head = [1], n = 1
    输出:[]
    示例 3:

    输入:head = [1,2], n = 1
    输出:[1]
     

    提示:

    链表中结点的数目为 sz
    1 <= sz <= 30
    0 <= Node.val <= 100
    1 <= n <= sz


    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    //最先找到的方案:先找到这个链表有多长,然后找到应该移除的节点。
        public ListNode removeNthFromEnd(ListNode head, int n) {
            //先找到这个链表有多长
            ListNode pre = new ListNode(-1,head); //这里pre的作用就是一个哑节点,标识从哪里开始
            int length = 0;
            ListNode cur = head;
            while(cur != null){
                length++;
                cur = cur.next;
            }
            if(length < n){
                return pre.next;
            }
            
    
            //这里为什么要设置 cur = pre?
            cur = pre;
            //为什么length - n + 1
                //举个例子:我们要length = 5 我们要去掉倒数第二个节点,那么这个节点正数应该是第4个 所以是 5-2+1;
            //其次,我们要找到的正数第四个节点,而是应该找到正数第三个节点
                //所以从1开始,且小于length - n + 1
            for(int i = 1; i< length - n + 1; i++){
                cur = cur.next;
            }
            //当前已经找到cur
            cur.next = cur.next.next;
            return pre.next;
        }

    优点:这是最容易想到的方案,劣势也很清楚,遍历了两次

    时间复杂度:O(n)

    空间复杂度:O(1)

    如何将遍历次数减少到一次呢?

    那就要借助双指针了:

    //第二个方案:使用双指针
            //1.执行一次遍历,找到n在哪个位置 这是第一个指针
            //2.执行第二次遍历,第一个指针指向结束,第二个指针指向当前节点
        public ListNode removeNthFromEnd(ListNode head, int n) {
            //
            ListNode pre = new ListNode(-1,head); //这里pre的作用就是一个哑节点,标识从哪里开始
            
            ListNode first = head; //第一个指针
    
            //第一次遍历到第n个结束
            for(int i = 1; i<= n; i++){
                first = first.next;
            }
            
            ListNode second = pre; //第二个指针
    
            //第二次遍历,遍历到第一个指针结束为止
            while(first != null){
                second = second.next;
                first = first.next;
            }
            second.next = second.next.next;
            return pre.next;
        }
    一个入行不久的Java开发,越学习越感觉知识太多,自身了解太少,只能不断追寻
  • 相关阅读:
    第2天 轻量级RPC框架开发
    028_ajax的String,View,Object执行流程
    027_获取隐藏id值的两种方式
    009_myBatis删除多条记录open="(",写成了index="(".
    026_一次性删除多条数据的sql语句
    025_json请求头与form表单请求头?
    024_如何生成一个32位的uuid?
    023_如何实现一次性删除多条记录?
    022_同步请求与异步请求的区别?
    021_SpringMVC中拦截器的作用?
  • 原文地址:https://www.cnblogs.com/fengtingxin/p/14757160.html
Copyright © 2020-2023  润新知