【数据结构】- 面试题

news2025/2/3 20:46:32

面试题

  • 1. 删除链表中的节点
  • 2. 反转一个链表(非递归解法)
  • 3. 判断一个链表是否有环(快慢指针)
    • 问题:[快慢指针为什么一定会相遇](https://blog.csdn.net/Leslie5205912/article/details/89386769)
  • 4. 获取单链表的节点个数
  • 5. 查询单链表中倒数第K个节点
  • 6. 逆序打印单向链表(栈)
  • 7. 约瑟夫环问题
    • 1. 构建环形链表并遍历
    • 2. 出圈

1. 删除链表中的节点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void deleteNode(ListNode node) {
        node.val = node.next.val;
        node.next = node.next.next;
    }
}

2. 反转一个链表(非递归解法)

在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode newHead = null;
        while (head != null) {
            ListNode tmp = head.next;
            head.next = newHead;
            newHead = head;
            head = tmp;
        }
        return newHead;
    }
}

3. 判断一个链表是否有环(快慢指针)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head == null || head.next == null) return false;
        ListNode slow = head;
        ListNode fast = head.next; // 快指针每次都比慢指针快一步(包括开始)
        while (fast != null && fast.next != null) {
            if (slow.val == fast.val) return true;
            slow = slow.next;
            fast = fast.next.next;
        }
        return false;
    }
}

问题:快慢指针为什么一定会相遇

慢指针每次移动一格,快指针每次移动两格,在有环的链表里,他们一定会相遇
1、当快指针就在慢指针后面,那么下一次慢指针移动一位,快指针移动两位,相遇
2、当快指针和慢指针差一个位置,那么下一次慢指针移动一位,快指针移动两位,他们会变成第一种情况
3、当快指针和慢指针差两个位置,那么下一次慢指针移动一位,快指针移动两位,他们会变成第二种情况
我知道你也在纠结为什么会没有快指针跳过慢指针他们没有相遇的这种情况发生,但是这种情况只会发生在他们相遇后的下一次移动
原因:其实从上面的三步不难看出:快指针是一格一格追赶慢指针的,即他们的距离是…4->3->2->1->0这样缩短的。所以一定会相遇

4. 获取单链表的节点个数

public static int getLinkListNodeLength(Node head){
	if(head == null){
		return 0;
	}
	int length = 0;
	Node currentNode = head;
	//如果链表不为空,则长度加1并且当前结点指向下一个结点
	while(currentNode != null){
		length++;
		currentNode = currentNode.next;
	}
	return length;
}

5. 查询单链表中倒数第K个节点

static Node getLastIndex(Node first, int k) {
  	    //1. 链表为空
        if (first == null) {
            return null;
        }
        //2.遍历得到链表长度
        int length = getLinkListNodeLength(first);
        //2.1 k校验
        if (k < 0 || k > length) {
            return null;
        }

        //3. 从第一个开始遍历,遍历到length-k结束
        Node cur = first;
        for (int i = 0; i < length - k; i++) {
            cur = cur.next;
        }
        return cur;
}

6. 逆序打印单向链表(栈)

LinkedList linkedList = new LinkedList<Integer>();
linkedList.add(0,0);
linkedList.add(1,1);
linkedList.add(2,2);
linkedList.add(3,3);

Stack<Integer> stacks = new Stack<>(); //先进后出
//将元素压入栈
LinkedList.Node cur = linkedList.getFirst();
while (cur != null) {
    stacks.push((Integer) cur.element);
    cur = cur.next;
}
//元素出栈
while (stacks.size() > 0) {
    System.out.println(stacks.pop());
}

在这里插入图片描述

7. 约瑟夫环问题

在这里插入图片描述

1. 构建环形链表并遍历

在这里插入图片描述

2. 出圈

在这里插入图片描述

public class JosepfuDemo {
    public static void main(String[] args) {
        CircleSingleLinkedList circleSingleLinkedList = new CircleSingleLinkedList();
        circleSingleLinkedList.addBoy(5);
        circleSingleLinkedList.show();
        circleSingleLinkedList.countBoy(1, 2, 5);
    }
}

class CircleSingleLinkedList {
    private Boy first;

    void addBoy(int nums) {
        Boy cur = null;//指向最后一个节点
        for (int i = 1; i <= nums; i++) {
            Boy boy = new Boy(i);
            if (i == 1) {
                first = boy;
                first.setNext(first); //组成环
                cur = boy;
            } else {
                cur.setNext(boy); //当前节点加入环
                boy.setNext(first); //组成环
                cur = boy; //指向最后一个节点
            }
        }
    }

    /**
     * @param startNo  从第几个小孩开始
     * @param countNum 数多少下
     * @param nums     一共多少小孩
     */
    void countBoy(int startNo, int countNum, int nums) {
        // 先对数据进行校验
        if (first == null || startNo < 1 || startNo > nums) {
            System.out.println("参数输入有误, 请重新输入");
            return;
        }

        //创建辅助指针,指向最后一个元素
        Boy helper = first;
        while (true) {
            if (helper.getNext() == first) {
                break;
            }
            helper = helper.getNext();
        }

        //小孩报数前,先让 first 和  helper 移动 k - 1次
        for (int i = 0; i < startNo - 1; i++) {
            helper = helper.getNext();
            first = first.getNext();
        }

        while (true) {
            if (first == helper) {
                System.out.println("最后一个小孩:" + first.getNo());
                break;
            }

            //让 first 和  helper 移动 m - 1次 (假设m是2,只需要移动一次,自己喊1,下一个就是被移除的元素)
            for (int i = 0; i < countNum - 1; i++) {
                helper = helper.getNext();
                first = first.getNext();
            }
            //这时first指向的节点,就是要出圈的小孩节点
            System.out.println("出圈:" + first.getNo());
            //元素出圈
            first = first.getNext();
            helper.setNext(first);
        }
    }


    void show() {
        Boy cur = first;
        while (true) {
            System.out.println(cur.getNo());
            if (cur.getNext() == first) {
                break;
            }
            cur = cur.getNext();
        }
    }
}

class Boy {
    private int no;
    private Boy next;

    public Boy(int no) {
        this.no = no;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public Boy getNext() {
        return next;
    }

    public void setNext(Boy next) {
        this.next = next;
    }
}

在这里插入图片描述

问题1-3参考:https://luzhenyu.blog.csdn.net/article/details/104609375
问题4参考:获取单链表的节点个数:https://blog.csdn.net/jcm666666/article/details/52278471
快慢指针为什么一定会相遇:https://blog.csdn.net/Leslie5205912/article/details/89386769
约瑟夫环问题:https://www.bilibili.com/video/BV1E4411H73v?p=28&vd_source=b901ef0e9ed712b24882863596eab0ca

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/103659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【轻量级开源ROS 的机器人设备(5)】--(3)拟议的框架——µROS节点

前文链接&#xff1a;(2条消息) 【轻量级开源ROS 的机器人设备&#xff08;5&#xff09;】--&#xff08;2&#xff09;拟议的框架——ROS节点 五、静态栈分析 在处理运行多个资源的严格受限平台时线程&#xff0c;重要的是将堆栈使用保持在最低限度。这甚至 在利用具有同质堆…

技嘉电脑怎么开启vt模式?

电脑开启vt模式后&#xff0c;可以提高主板的运行速率&#xff0c;提高性能。那就有一些使用技嘉电脑的用户问技嘉主板怎么开启vt模式&#xff1f;下面小编就来教教大家技嘉电脑开启vt模式的方法。 Intel芯片组的技嘉主板 1、一般情况下&#xff0c;也就是在电脑开机的时候&…

计算机网络、操作系统刷题笔记15

计算机网络、操作系统刷题笔记15 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其sq…

差分详细讲解(C++)

每日一句:平凡的我在人多的地方曾极力小心翼翼&#xff0c; 但不知从何时起 &#xff0c;我不太在意别人的目光了。比起被人觉得是个怪人&#xff0c;我现在更害怕浪费时间。 差分一、一维差分二、二维差分一、一维差分 差分就是前缀和的逆运算,如果你不懂什么是前缀和,看这里…

移动技术在仓库运营管理中的作用

作者&#xff1a;Mike Kay&#xff0c;Mendix公司合作伙伴The Config Team渠道客户经理 市面上出现越来越多的仓库管理系统&#xff08;WMS&#xff09;以满足企业更好地管理供应链的需求。想要充分挖掘WMS的优点&#xff0c;一般可以通过移动解决方案来将关键的供应链运作进…

浪潮信息工程师:带你了解设备透传虚拟机的快速启动技术优化方案

编者按&#xff1a;将物理设备通过 vfio 透传给虚拟机是虚拟化常用的技术&#xff0c;但当为虚拟机分配比较大的内存时&#xff0c;虚拟机的启动时间会明显变慢&#xff0c;可能由十几秒延长至数分钟&#xff0c;严重影响用户使用体验。本文整理自龙蜥大讲堂 51 期&#xff0c;…

小林coding阅读笔记:计算机网络基础篇-TCP\IP模型

前言 参考/导流&#xff1a; 小林coding - 2.1 TCP/IP 网络模型有哪几层&#xff1f;学习意义 学习分层设计思想构建网络层次以及各层协议作用知识体系为网络编程奠定理论基础&#xff0c;对于RPC框架or分布式系统通信都是极为重要的一节&#xff0c;是提升整个系统效率的关键…

ubunt配置samba服务器,匿名访问

1. 环境 ubuntu14.04 2. 安装samba服务器 sudo apt-get install samba 3. 配置samba文件 vim /etc/samba/smb.conf 在最后添加如下内容 [muchx]comment Shared Folder with username and passwordpath /home/muchx/sharepublic yeswritable yesvalid users muchxcre…

二、基于kubeadm安装kubernetes1.25集群第一篇

1、概述 Kubeadm 是一个提供了 kubeadm init 和 kubeadm join 的工具&#xff0c; 作为创建 Kubernetes 集群的 “快捷途径” 的最佳实践。 kubeadm 通过执行必要的操作来启动和运行最小可用集群。 按照设计&#xff0c;它只关注启动引导&#xff0c;而非配置机器。同样的&…

虹科分享 | 硬件加密U盘 | 管理密码安全的四大工具

随着网络攻击变得越来越突出&#xff0c;密码安全变得越来越重要。为了为每个帐户创建安全密码&#xff0c;许多人正在转向密码管理工具来帮助防止敏感数据的泄露。 考虑到这一点&#xff0c;以下是一些顶级密码管理工具。 领先的密码管理工具 Keeper密码管理器和数字保险库 …

kali linux手动编译网卡驱动(以mt7612u为例)

〇、linux常用命令 《Linux入门与基础》课程教案_小王小王指定辉煌的博客-CSDN博客_linux入门与基础教案 linux常用命令笔记&#xff08;二&#xff09;_小王小王指定辉煌的博客-CSDN博客 一、下载源码 查看系统版本号 uname -r uname -a cat /proc/version 或/lib/module…

手撕红黑树的构建与验证

上篇文章我们介绍了AVL树的构建与适用场景&#xff0c;我们知道了AVL树虽然查找效率很高&#xff0c;但是不适合频繁插入或删除的场景。为了解决这个问题又诞生了新的数据结构&#xff1a;红黑树 那么本篇文章就着重介绍红黑树的性质与如何构建。 1.红黑树的性质 1.结点颜色非黑…

邓俊辉 《数据结构》笔记1 绪论

邓俊辉 《数据结构》笔记1 绪论 CSDN转图床总是崩&#xff0c;如果全写完再上传一次要调好多&#xff0c;感觉很麻烦&#xff0c;所以写一点更新一点&#xff0c;会持续更新 提前发出来还有个好处就是push自己更新不会咕咕咕&#xff0c;哈哈 参考资料 MOOC 数据结构上MOOC 数…

【计算机考研408】磁盘的初始化过程

该图是磁盘物理图 关于磁盘存储器&#xff0c;[柱面号盘面号扇区号]⇔外存块号 注&#xff1a;柱面是相对位置相同的磁道所构成的面 磁盘初始化 低级初始化&#xff08;也称物理格式化&#xff09; &#xff08;1&#xff09;分扇区 &#xff08;2&#xff09;用特殊数据结构…

linux后台自定义后台服务service(以filebeat举例)

文章目录一、配置攥写1&#xff09;安装filebeat和配置相关修改2&#xff09;常用命令二、启动顺序1&#xff09;命令循序2&#xff09;systemctl添加自定义系统服务&#xff08;服务填写指南&#xff09;3&#xff09;linux的systemctl命令详解及使用教程三、遇到的坑点和报错…

谁再要你自学网络安全,请给他一大B兜

前言 作为一名6年网安工程师老菜鸟来说&#xff0c;我实在想不通&#xff0c;开发岗位那么多&#xff0c;为什么要来学网安? 在这里必须给那些准备入坑的同学泼几盆冷水&#xff01;零基础自学网络安全&#xff1f;劝你还是别做梦了&#xff01; 基础确实很简单&#xff0c…

2023火爆共享购商业模式概念、框架、基础制度

各位企业家及创业者朋友们&#xff0c;你们好。我是微三云&#xff08;陈志坤&#xff09;&#xff0c;在你打开这个文章的时候&#xff0c;先不要急&#xff0c;因为任何一个能够长久、安稳、盈利的平台&#xff0c;背后肯定有一位看准宏观方向且耐心的人。这是一个极具颠覆性…

算法图论篇

文章目录一、DFS1.排列数字&#xff08;全排列&#xff09;2.n皇后3.树的重心二、BFS1.走迷宫2.八数码3.图中点的层次三、拓扑排序1.有向图的拓扑序列四、最短路1.Dijkstra2. bellman-ford3.spfa4.floyd五、求最小生成树1.Prim算法2.Kruskal算法六、二分图1.染色法判定二分图2.…

UWB汽车钥匙介绍

汽车钥匙经历了机械钥匙、遥控钥匙、PEPS、数字钥匙四个阶段&#xff0c;而数字钥匙又分为BLE/NFC/UWB三种技术路线。 由于UWB安全性、定位精度、作用范围明显好于BLE和NFC&#xff0c;因此成为汽车数字钥匙的最优技术。 PEPS与数字钥匙: PEPS是指无钥匙进入/无钥匙启动系统&a…

【爬虫】JS调试解决反爬问题系列2

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…