每日一题 为了工作 2020 0315 第十三题

Posted walxt

tags:

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

/*双向链表

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方

便地访问它的前驱结点和后继结点。

下图是双向链表的逻辑结构图,和单链表不同的是,双向链表中每个节点包含两个节点的指针引用,和一个数据域,这两个节点分别指向前一个节点和后一个节点;

双向链表的这种结构比起单链表,其改进之处正在于此,通过对前后节点的引用可以使得在整个链表中,通过给定的值,可以从前或者向后遍历,大大提升了遍历

查询的效率,一定程度上解决了单链表的性能问题,但与此同时,链表的存储开销也增大了,我们熟悉的linkedList,其底层就是这个原理实现的。

技术图片

 

 

/**
* 题目:在双链表中删除倒数第K个节点
* 实现函数可以删除双链表中的倒数第K个节点。
* 要求:
* 如果链表长度为N,时间复杂度为O(N),额外空间复杂度达到O(1)。
* 分析:
* 1.如果链表为空或者 K值小于1, 这种情况下, 参数是无效的, 直接返回即可。
* 除此之外, 让链表从头开始走到尾, 每移动一步, 就让 K的值减1。
*
* 链表: 1->2->3, K=4, 链表根本不存在倒数第4个节点
* 走到的节点: 1 -> 2 -> 3
* K变化为: 3 2 1
*
* 链表: 1->2->3, K= 3, 链表倒数第3个节点是l 节点。
* 走到的节点: 1 -> 2 -> 3
* K变化为: 2 I 0
*
* 链表: 1->2->3, K=2, 链表倒数第2个节点是2节点。
* 走到的节点: 1 -> 2 -> 3
* K变化为: 1 0 1
*
* 由以上三种情况可知, 让链表从头开始走到尾, 每移动一步, 就让 K值减 1, 当链表
*走到结尾时, 如果 K值大于0, 说明不用调整链表, 因为链表根本没有倒数第 K个节点,
*此时将原链表直接返回即可;
*
* 如果 K值等于0, 说明链表倒数第K个节点就是头节点, 此时直接返回head.next,
*也就是原链表的第二个节点,让第二个节点作为链表的头返回即可,相当于删除头节点;
*
* 如果K值小于0,首先明确一点, 如果要删除链表的头节点之后的某个节点, 实际上需要
*找到要删除节点的前一个节点, 比如: 1->2->3, 如果想删除节点2, 则需要找到节点1,
*然后把节点1连到节点3上(1->3), 以此来达到删除节点2的目的。
*
* 如果K值小于0, 如何找到要删除节点的前一个节点呢?方法如下:
*1. 重新从头节点开始走, 每移动一步, 就让 K的值加 1。
*2. 当 K等于 0时, 移动停止, 移动到的节点就是要删除节点的前一个节点。
*
* 如果链表长度为N, 要删除倒数第K个节点, 很明显,倒数第K个节点的前一个节点就是
*第 N-K个节点。在第一次遍历后, K的值变为 K-N。第二次遍历时,K的值不断加1,加到 0
*就停止遍历, 第二次遍历当然会停到第 N-K个节点的位置。
*
* 注意:
* 要注意 last指针的重连。
* @author 雪瞳
*
*/

public class DoubleNode {
    public int value;
    public DoubleNode next;
    public DoubleNode last;
    public DoubleNode(int data) {
        this.value=data;
    }
}
public class ReamoNode {
    
    public DoubleNode removeLastKthNode(DoubleNode head , int K) {
        if(K<0 || head == null) {
            return null;
        }
        DoubleNode cur = head;
        while(cur!=null) {
            K = K-1;
            cur = cur.next;
        }
        if(K==0) {
            head = head.next;
            head.last = null;
        }
        if(K<0) {
            cur = head;
            //先自增在判断,如果自增完成后不满足判断条件,说明当前节点cur的下一个节点就是需要删除的节点
            while(++K != 0) {
                cur = cur.next;
            }
            //将当前节点与下一个节点的下一节点相连接
            DoubleNode newNext =cur.next.next;
            cur.next = newNext;
            //若newNext不是空则需要将cur和newNext相连
            if(newNext != null) {
                newNext.last = cur;
            }
        }
        return head;
    }
}
import java.util.Random;
import java.util.Scanner;

public class testRemoveNode {
	public static void main(String[] args) {
		testRemoveNode test = new testRemoveNode();
		ReamoNode remove = new ReamoNode();
		Random rand = new Random();
		DoubleNode nodes[]=new DoubleNode[10];
		Scanner sc = new Scanner(System.in);
		System.out.print("请输入需要删除倒数第几个节点 K=");
		int K = sc.nextInt();
		
		for(int i=0;i<nodes.length;i++) {
			nodes[i]=new DoubleNode(rand.nextInt(10));
		}
		for(int i =0;i<nodes.length-1;i++) {
			nodes[i].next=nodes[i+1];
		}
		
		test.showNode(nodes[0]);
		remove.removeLastKthNode(nodes[0], K);
		test.showNode(nodes[0]);
	}
	public void showNode(DoubleNode head) {
		System.out.println("链表内的元素如下所示...");
		while(head != null) {
			System.out.print(head.value+"	");
			head = head.next;
		}
		System.out.println();
	}
}

  

 

以上是关于每日一题 为了工作 2020 0315 第十三题的主要内容,如果未能解决你的问题,请参考以下文章

每日一题 为了工作 2020 0325 第二十三题

每日一题 为了工作 2020 0305 第三题

每日一题 为了工作 2020 03019 第十七题

每日一题 为了工作 2020 0312 第十题

每日一题 为了工作 2020 0317 第十五题

刷题的狂欢-----JAVA每日三练-----第十三天