精华内容
下载资源
问答
  • 另外,如果我们已知了链表的长度,为n,那么倒数第k个节点,也就是从前往后n-k+1个节点,我们从前往后遍历n-k+1即可,然而我们并不知道链表的长度,所以需要先遍历一遍链表,才能取得它长度,再遍历一边链...

    题目描述

    输入一个链表,输出该链表中倒数第k个结点。

    首先想到的是从头结点开始遍历到链表的末尾,然后往前回溯k个节点,但是回溯?  这种方式只适用于双向链表,对于单向链表,是不可行的。

    另外,如果我们已知了链表的长度,为n,那么倒数第k个节点,也就是从前往后的第n-k+1个节点,我们从前往后遍历n-k+1即可,然而我们并不知道链表的长度,所以需要先遍历一遍链表,才能取得它的长度,再遍历一边链表,才能输出第k个节点。所以这种方法的时间复杂度较高,需要遍历两遍才可以输出。

    实现1:

    public ListNode FindKthToTail(ListNode head,int k) {
            ListNode p=head;
            if(head==null||k==0){
                return null;
            }
            int length=1;
            while(head.next!=null){
                head=head.next;
                length++;
            }
            if(k>length){
                return null;
            }
            for (int i = 1; i <length-k+1; i++) {
                if(p.next!=null){
                    p=p.next;
                }
                else{
                    return null;   
                }  
            }
            return p;
     
        }

    实现2:用堆栈的方式去实现

     public ListNode FindKthToTail(ListNode head,int k) {
            ListNode result=null;
    		if(head==null||k==0){
    			return null;
    		}
    		Stack<ListNode> s=new Stack<>();
    		while(head!=null){
    			s.push(head);
    			head=head.next;
    		}
    		for (int i =1; i <= k; i++) {
    			if(!s.isEmpty()){
    				result=s.pop();
    			}else{
    				result=null;
    			}			
    		}
    		return result;
        }

    上面的这两种实现时间复杂度太高,并不是我们期望的结果。

    如果想要只遍历一遍链表,就输出倒数的第k个元素,那么我们就需要两个指针。

    (1)开始,让指针p1,p2都指向头结点,指针2先不动,指针1向前走k-1步;此时p1和p2之间相差k-1;

    (2)从第k步开始,p1和p2同时移动,当p1指向链表的末尾时,此时p1所指的元素就是倒数第k个元素。

     

    初步实现:

    public ListNode FindKthToTail2(ListNode head,int k) {
            ListNode p1=head;
            ListNode p2=head;
            //第一个指针先走,直到遍历到链表的第k-1个节点
            for (int i = 1; i <=k-1; i++) {
                p1=p1.next;
            }
            //此时p1和p2之间相差k-1个元素,现在两个指针同时遍历
            while(p1.next!=null){
                p1=p1.next;
                p2=p2.next;
            }
            return p2;

        }

    这个实现是有问题的,会报空指针异常,因为代码中存在多种特殊的情况没有被考虑到。

    首先,如果给了一个空链表,那它的next是不存在的,此时会报错,

    其次,如果给的k=0,则k-1=-1,也会报错;

    另外,需要返回的k大于所给的链表的总长度时,也会报错,

    考虑到以上情况,对代码做一些安全性的考虑,实现如下:

    实现3:

     public ListNode FindKthToTail(ListNode head,int k) {
            if(head==null||k==0){
                return null;
            }
            ListNode p1=head;
            ListNode p2=head;
            //第一个指针先走,直到遍历到链表的第k-1个节点
            for (int i = 1; i <=k-1; i++) {
                if(p1.next!=null){
                    p1=p1.next;
                }
                else{
                    return null;
                }
            }
            //此时p1和p2之间相差k-1个元素,现在两个指针同时遍历
            while(p1.next!=null){
                p1=p1.next;
                p2=p2.next;
            }
            return p2;
     

     

    扩展题:删除链表的倒数第n个节点

    题目描述:

    题目:给定一个链表,删除链表的倒数第 N 个节点,并且返回链表的头结点。

    ◼ 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5. 说明: 给定的 n 保证是有效的。 要求: 只允许对链表进行一次遍历。

    思路:

    和上面是一样的,使用快慢两个指针,第一个指针从列表的开头向前移动 n+1 步,而第二个指针将从列表的开头出发。现在,这两个指针被 n 个结点分开。我们通过同时移动两个指针向前来保持这个恒定的间隔,直到第一个指针到达最后一个结点。此时第二个指针将指向从最后一个结点数起的第 n 个结点。我们重新链接第二个指针所引用的结点的 next 指针指向该结点的下下个结点。

    实现:

    public ListNode removeNthFromEnd(ListNode head, int n)
    {
    	ListNode dummy = new ListNode(0);
    	dummy.next = head;
    	ListNode first = dummy;
    	ListNode second = dummy;
    
    	for (int i = 1; i <= n + 1; i++) {
    		first = first.next;
    	}
    	// Move first to the end, maintaining the gap
    	while (first != null) {
    		first = first.next;
    		second = second.next;
    	}
    	second.next = second.next.next;
    	return dummy.next;
    }

    参考:

    http://www.cnblogs.com/edisonchou/p/4769164.html

    展开全文
  • 题目描述:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 题目分析:该题首先得确定所给链表是否为空以及节点总数,然后确定需要删除节点是正数第几个,然后再进行删除操作。同时对于特殊...
    • 题目描述:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。
      在这里插入图片描述
    • 题目分析:该题首先得确定所给链表是否为空以及节点总数,然后确定需要删除的节点是正数第几个,然后再进行删除操作。同时对于特殊长度或特殊位置的节点需要进行单独处理,比如链表为空,或者长度为1,删除第一个或最后一个节点等。
    • 代码展示:
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    class Solution {
        public ListNode removeNthFromEnd(ListNode head, int n) {
            int j;//删除的是正数第j个结点
            int k = 1;
            int i = 0;//统计结点总数
            if(head == null) {return head;}
            ListNode list1 = head;
            while(list1 != null) {
                i++;
                list1 = list1.next;
            }
            if(n == i) {head = head.next; return head;}
            if(i == 1) {return null;}
            j = i - n + 1;
            list1 = head;
            while(k < j - 1) {
                list1 = list1.next;
                k ++;
            }
            if(n == 1) {
                list1.next = null;
                return head;            
            }
            list1.next = list1.next.next;
            return head;
        }
    }
    
    展开全文
  • 注意需要设置哨兵节点,否则对于只有一个节点的链表,该算法无法处理。 Java代码 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * .

    19. 删除链表的倒数第N个节点


    解题思路

    利用双指针,将快指针提前前进 n + 1 个节点,然后同时移动快慢指针。当快指针指向 null 时,慢指针恰好指向需要删除的节点的前一节点。

    注意需要设置哨兵节点,否则对于只有一个节点的链表,该算法无法处理。

     

    Java代码

    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    class Solution {
        public ListNode removeNthFromEnd(ListNode head, int n) {
            ListNode guard = new ListNode(0);
            guard.next = head;
            ListNode fast = guard;
            ListNode slow = guard;
            for (int i = 0; i <= n; i++) fast = fast.next;
            while (fast != null) {
                fast = fast.next;
                slow = slow.next;
            }
            slow.next = slow.next.next;
            return slow == guard ? slow.next : head;
        }
    }

     

    展开全文
  • 题目 给定一个链表,删除链表的...用双指针就可以一趟扫描实现链表节点的删除,但是需要注意对于第一个节点的删除,在实现过程中通过dummyHead来保证对于第一个节点的删除与对其它节点的删除操作相同,这样就保证了对第

    题目

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

    示例:

    给定一个链表: 1->2->3->4->5, 和 n = 2.
    
    当删除了倒数第二个节点后,链表变为 1->2->3->5.
    

    说明:

    给定的 n 保证是有效的。

    进阶:

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

    思路

    用双指针就可以一趟扫描实现链表节点的删除,但是需要注意对于第一个节点的删除,在实现过程中通过dummyHead来保证对于第一个节点的删除与对其它节点的删除操作相同,这样就保证了对第一个节点删除不会出错误。

    代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode *dummyHead = new ListNode(0);
            dummyHead -> next = head;
            ListNode *cur = head, *before = dummyHead, *last = head;
            while(n > 0){
                last = last -> next;
                n--;
            }
            while(last != NULL){
                before = before -> next;
                cur = cur -> next;
                last = last -> next;
            }
            before -> next = cur -> next;
            delete cur;
            return dummyHead -> next;
        }
    };
    
    展开全文
  • 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 给定的链表的头结点是第一个结点(有值)。 两次遍历算法 最简单的方法,但实现并不简单,对于只有一个结点的情况很难处理(的优雅),所以这个时候...
  • 删除链表倒数第N个节点,直观想到的是遍历两次。为了节约运行时间,题目提示了能否遍历一次完成。因而以下做法都只涉及遍历一次链表对于链表操作,有一个**小技巧**。通常在head前加一个哑元,避免对头节点的特判...
  • 给定一个链表,删除链表的倒数第n个节点,并且返回链表的头结点。 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5. 说明: 给定 n保证...
  • 对于头节点来说,其没有前一个节点,因此,需定义虚拟头节点,如下图: 这里要删除链表中倒数第2个节点,其前一个节点是指针slow指向节点。 那如何确定指针slow指向位置呢?在这里还需引入指针fast,当...
  • 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5. 说明: 给定 n 保证...
  • LeetCode 每日一题----19删除链表的倒数第n个节点 题目 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后...
  • 链表的解决方法一般都是靠指针,这个很容易能想到快慢指针做法,对于要删除倒数第n个,我们就让快指针先走n步,然后让慢指针出发,接着两者一起走,当快指针指向空时,则慢指针就是我们要求点。 有以下几点需要...
  • 给定一个链表,删除链表的倒数第n个节点,并且返回链表的头结点。 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二个节点后,链表变为 1->2->3->5.说明: 给定 n保证是...
  • 第二题要求对链表读取,对于节点对象创建,对于链表的创建。 这道题其实就考察了对于链表的删除 目前我对于这类链表解题思路是,遍历一次链表,把节点用列表装起来,把对链表的操作转换为对于列表操作...
  • 题目描述: 输入一个链表,输出该链表中倒数第k个结点。(hint: 请务必使用链表。)输入: 输入可能包含多个测试样例,输入以EOF结束。...输入第二行包括n个数t(1&lt;=t&lt;=1000000):代表链表...
  • 19.删除链表的倒数第N个节点思路如果没有你能尝试使用一趟扫描实现吗?对大多数人来说应该是个简单题目,但是加了这个限制话,出题人肯定想考察一下其他知识点。对于这道题,采用双指针(但我觉...
  • 题目描述: 输入一个链表,输出该链表中倒数第k个结点。...输入第二行包括n个数t(1 输出: 对应每个测试案例, 若有结果,输出相应查找结果。否则,输出NULL。 样例输入:
  • 个链表的公共节点

    2020-02-13 22:26:24
    题目 输入两个链表,找到它们第一公共节点链表节点定义如下: class ListNode{ public int n; public ListNode next;... public ListNode(int n){ ...暴力算法,对于第一个链表的节...
  • 心得:对于链表问题,加头指针可能简化问题 /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class ...
  • 如果没有哑节点,对于只有head,则很难删除这个节点。设置dummy.next = head; dummy.next =None,同时返回dummy.next 思路一:双指针方法 # Definition for singly-linked list. # class ListNode: # def __init...
  • 对于第一个链表,每访问一个节点,对该节点做标记。访问第二个链表,如果该元素已经访问,则第一个这样元素就是所求点。 由于两个链表都访问了一遍,因此时间复杂度O(m+n),空间复杂度O(m)或O(n) 方法2.我们...
  • 1、蛮力算法,当遍历到一个节点时,就在另外一个链表上顺序遍历,并且判断是否相等,如果想等就是第一个重合的节点,对于两个长度分别为m和n的链表,所需要的时间为O(m*n)。实现如下: struct ListNode { int val...
  • 给定一个链表,返回链表开始入环第一个节点。如果链表无环,则返回NULL OJ链接 思路: 对于这样一个带环链表进环之前长度为L,环长度为C,使用快慢指针,找到相遇结点,结点位置距离环入口为K,则...
  • 问题 删除一个未排序链表重复节点,例如 输入:1-4-2-6-3-2-4-1 ...(2)不使用额外空间,对于每一个节点,遍历后续节点看是否存在重复,如果重复则删除; time:o(n^2) space:o(1) /** * 问题:删除一个未排...
  • (2)对于删除倒数第K个节点,为了保证得到删除节点父节点的信息,慢指针要慢于快指针第K步前进。 (3)两者均要注意当链表长度不足时边界条件的定义。对于删除问题,尤其要注意删除第一个元素(倒数第N个)时,链表...
  • 题目:输出链表的倒数第k个节点 分析: 方法一: 先遍历链表,得到链表的总长度n,然后再次从头遍历链表定位到第... 设两个头指针,第一个头指针往下遍历,直到第k-1个节点的时候停止,然后两个指针同时向后遍历,
  • 对于链表中倒数第 k 个节点」,需要时刻维护一个前置节点,最终left指向节点就是需要删除节点; 当然,也可以不用维护,通过设置哨兵方式,使得最终left.next就是需要删除节点,最后让left.next = left....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 582
精华内容 232
关键字:

对于n个节点的链表