常见の算法链表问题

时间复杂度

1.链表逆序

package class04;import java.util.ArrayList;
import java.util.List;public class Code01_ReverseList {public static class Node {public int value;public Node next;public Node(int data) {value = data;}}public static class DoubleNode {public int value;public DoubleNode last;public DoubleNode next;public DoubleNode(int data) {value = data;}}public static Node reverseLinkedList(Node head) {Node pre = null;Node next = null;while (head != null) {next = head.next;head.next = pre;pre = head;head = next;}return pre;}public static DoubleNode reverseDoubleList(DoubleNode head) {DoubleNode pre = null;DoubleNode next = null;while (head != null) {next = head.next;head.next = pre;head.last = next;pre = head;head = next;}return pre;}public static Node testReverseLinkedList(Node head) {if (head == null) {return null;}ArrayList<Node> list = new ArrayList<>();while (head != null) {list.add(head);head = head.next;}list.get(0).next = null;int N = list.size();for (int i = 1; i < N; i++) {list.get(i).next = list.get(i - 1);}return list.get(N - 1);}public static DoubleNode testReverseDoubleList(DoubleNode head) {if (head == null) {return null;}ArrayList<DoubleNode> list = new ArrayList<>();while (head != null) {list.add(head);head = head.next;}list.get(0).next = null;DoubleNode pre = list.get(0);int N = list.size();for (int i = 1; i < N; i++) {DoubleNode cur = list.get(i);cur.last = null;cur.next = pre;pre.last = cur;pre = cur;}return list.get(N - 1);}// for testpublic static Node generateRandomLinkedList(int len, int value) {int size = (int) (Math.random() * (len + 1));if (size == 0) {return null;}size--;Node head = new Node((int) (Math.random() * (value + 1)));Node pre = head;while (size != 0) {Node cur = new Node((int) (Math.random() * (value + 1)));pre.next = cur;pre = cur;size--;}return head;}// for testpublic static DoubleNode generateRandomDoubleList(int len, int value) {int size = (int) (Math.random() * (len + 1));if (size == 0) {return null;}size--;DoubleNode head = new DoubleNode((int) (Math.random() * (value + 1)));DoubleNode pre = head;while (size != 0) {DoubleNode cur = new DoubleNode((int) (Math.random() * (value + 1)));pre.next = cur;cur.last = pre;pre = cur;size--;}return head;}// for testpublic static List<Integer> getLinkedListOriginOrder(Node head) {List<Integer> ans = new ArrayList<>();while (head != null) {ans.add(head.value);head = head.next;}return ans;}// for testpublic static boolean checkLinkedListReverse(List<Integer> origin, Node head) {for (int i = origin.size() - 1; i >= 0; i--) {if (!origin.get(i).equals(head.value)) {return false;}head = head.next;}return true;}// for testpublic static List<Integer> getDoubleListOriginOrder(DoubleNode head) {List<Integer> ans = new ArrayList<>();while (head != null) {ans.add(head.value);head = head.next;}return ans;}// for testpublic static boolean checkDoubleListReverse(List<Integer> origin, DoubleNode head) {DoubleNode end = null;for (int i = origin.size() - 1; i >= 0; i--) {if (!origin.get(i).equals(head.value)) {return false;}end = head;head = head.next;}for (int i = 0; i < origin.size(); i++) {if (!origin.get(i).equals(end.value)) {return false;}end = end.last;}return true;}public static void f(Node head) {head = head.next;}// for testpublic static void main(String[] args) {int len = 50;int value = 100;int testTime = 100000;System.out.println("test begin!");for (int i = 0; i < testTime; i++) {Node node1 = generateRandomLinkedList(len, value);List<Integer> list1 = getLinkedListOriginOrder(node1);node1 = reverseLinkedList(node1);if (!checkLinkedListReverse(list1, node1)) {System.out.println("Oops1!");}Node node2 = generateRandomLinkedList(len, value);List<Integer> list2 = getLinkedListOriginOrder(node2);node2 = testReverseLinkedList(node2);if (!checkLinkedListReverse(list2, node2)) {System.out.println("Oops2!");}DoubleNode node3 = generateRandomDoubleList(len, value);List<Integer> list3 = getDoubleListOriginOrder(node3);node3 = reverseDoubleList(node3);if (!checkDoubleListReverse(list3, node3)) {System.out.println("Oops3!");}DoubleNode node4 = generateRandomDoubleList(len, value);List<Integer> list4 = getDoubleListOriginOrder(node4);node4 = reverseDoubleList(node4);if (!checkDoubleListReverse(list4, node4)) {System.out.println("Oops4!");}}System.out.println("test finish!");}}

2.单链表实现堆区跟队列

package class04;import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;public class Code02_LinkedListToQueueAndStack {public static class Node<V> {public V value;public Node<V> next;public Node(V v) {value = v;next = null;}}public static class MyQueue<V> {private Node<V> head;private Node<V> tail;private int size;public MyQueue() {head = null;tail = null;size = 0;}public boolean isEmpty() {return size == 0;}public int size() {return size;}public void offer(V value) {Node<V> cur = new Node<V>(value);if (tail == null) {head = cur;tail = cur;} else {tail.next = cur;tail = cur;}size++;}// C/C++的同学需要做节点析构的工作public V poll() {V ans = null;if (head != null) {ans = head.value;head = head.next;size--;}if (head == null) {tail = null;}return ans;}// C/C++的同学需要做节点析构的工作public V peek() {V ans = null;if (head != null) {ans = head.value;}return ans;}}public static class MyStack<V> {private Node<V> head;private int size;public MyStack() {head = null;size = 0;}public boolean isEmpty() {return size == 0;}public int size() {return size;}public void push(V value) {Node<V> cur = new Node<>(value);if (head == null) {head = cur;} else {cur.next = head;head = cur;}size++;}public V pop() {V ans = null;if (head != null) {ans = head.value;head = head.next;size--;}return ans;}public V peek() {return head != null ? head.value : null;}}public static void testQueue() {MyQueue<Integer> myQueue = new MyQueue<>();Queue<Integer> test = new LinkedList<>();int testTime = 5000000;int maxValue = 200000000;System.out.println("测试开始!");for (int i = 0; i < testTime; i++) {if (myQueue.isEmpty() != test.isEmpty()) {System.out.println("Oops!");}if (myQueue.size() != test.size()) {System.out.println("Oops!");}double decide = Math.random();if (decide < 0.33) {int num = (int) (Math.random() * maxValue);myQueue.offer(num);test.offer(num);} else if (decide < 0.66) {if (!myQueue.isEmpty()) {int num1 = myQueue.poll();int num2 = test.poll();if (num1 != num2) {System.out.println("Oops!");}}} else {if (!myQueue.isEmpty()) {int num1 = myQueue.peek();int num2 = test.peek();if (num1 != num2) {System.out.println("Oops!");}}}}if (myQueue.size() != test.size()) {System.out.println("Oops!");}while (!myQueue.isEmpty()) {int num1 = myQueue.poll();int num2 = test.poll();if (num1 != num2) {System.out.println("Oops!");}}System.out.println("测试结束!");}public static void testStack() {MyStack<Integer> myStack = new MyStack<>();Stack<Integer> test = new Stack<>();int testTime = 5000000;int maxValue = 200000000;System.out.println("测试开始!");for (int i = 0; i < testTime; i++) {if (myStack.isEmpty() != test.isEmpty()) {System.out.println("Oops!");}if (myStack.size() != test.size()) {System.out.println("Oops!");}double decide = Math.random();if (decide < 0.33) {int num = (int) (Math.random() * maxValue);myStack.push(num);test.push(num);} else if (decide < 0.66) {if (!myStack.isEmpty()) {int num1 = myStack.pop();int num2 = test.pop();if (num1 != num2) {System.out.println("Oops!");}}} else {if (!myStack.isEmpty()) {int num1 = myStack.peek();int num2 = test.peek();if (num1 != num2) {System.out.println("Oops!");}}}}if (myStack.size() != test.size()) {System.out.println("Oops!");}while (!myStack.isEmpty()) {int num1 = myStack.pop();int num2 = test.pop();if (num1 != num2) {System.out.println("Oops!");}}System.out.println("测试结束!");}public static void main(String[] args) {testQueue();testStack();}}

3.双链表结构实现双端队列

package class04;import java.util.Deque;
import java.util.LinkedList;public class Code03_DoubleLinkedListToDeque {public static class Node<V> {public V value;public Node<V> last;public Node<V> next;public Node(V v) {value = v;last = null;next = null;}}public static class MyDeque<V> {private Node<V> head;private Node<V> tail;private int size;public MyDeque() {head = null;tail = null;size = 0;}public boolean isEmpty() {return size == 0;}public int size() {return size;}public void pushHead(V value) {	//从头部加Node<V> cur = new Node<>(value);if (head == null) { //之前没有节点,cur是第一个head = cur;tail = cur;} else {cur.next = head;head.last = cur;head = cur;}size++;}public void pushTail(V value) {Node<V> cur = new Node<>(value);if (head == null) {head = cur;tail = cur;} else {tail.next = cur;cur.last = tail;tail = cur;}size++;}public V pollHead() {	//从头部弹出V ans = null;if (head == null) {return ans;}size--;ans = head.value;if (head == tail) {	//只有一个节点head = null;tail = null;} else {head = head.next;head.last = null;}return ans;}public V pollTail() {V ans = null;if (head == null) {return ans;}size--;ans = tail.value;if (head == tail) {head = null;tail = null;} else {tail = tail.last;tail.next = null;}return ans;}public V peekHead() {V ans = null;if (head != null) {ans = head.value;}return ans;}public V peekTail() {V ans = null;if (tail != null) {ans = tail.value;}return ans;}}public static void testDeque() {MyDeque<Integer> myDeque = new MyDeque<>();Deque<Integer> test = new LinkedList<>();int testTime = 5000000;int maxValue = 200000000;System.out.println("测试开始!");for (int i = 0; i < testTime; i++) {if (myDeque.isEmpty() != test.isEmpty()) {System.out.println("Oops!");}if (myDeque.size() != test.size()) {System.out.println("Oops!");}double decide = Math.random();if (decide < 0.33) {int num = (int) (Math.random() * maxValue);if (Math.random() < 0.5) {myDeque.pushHead(num);test.addFirst(num);} else {myDeque.pushTail(num);test.addLast(num);}} else if (decide < 0.66) {if (!myDeque.isEmpty()) {int num1 = 0;int num2 = 0;if (Math.random() < 0.5) {num1 = myDeque.pollHead();num2 = test.pollFirst();} else {num1 = myDeque.pollTail();num2 = test.pollLast();}if (num1 != num2) {System.out.println("Oops!");}}} else {if (!myDeque.isEmpty()) {int num1 = 0;int num2 = 0;if (Math.random() < 0.5) {num1 = myDeque.peekHead();num2 = test.peekFirst();} else {num1 = myDeque.peekTail();num2 = test.peekLast();}if (num1 != num2) {System.out.println("Oops!");}}}}if (myDeque.size() != test.size()) {System.out.println("Oops!");}while (!myDeque.isEmpty()) {int num1 = myDeque.pollHead();int num2 = test.pollFirst();if (num1 != num2) {System.out.println("Oops!");}}System.out.println("测试结束!");}public static void main(String[] args) {testDeque();}}

4.k个节点的组内逆序调整

reverse函数

package class04;// 测试链接:https://leetcode.com/problems/reverse-nodes-in-k-group/
public class Code04_ReverseNodesInKGroup {// 不要提交这个类public static class ListNode {public int val;public ListNode next;}public static ListNode reverseKGroup(ListNode head, int k) {ListNode start = head;ListNode end = getKGroupEnd(start, k);if (end == null) {	//第一组小于k个return head;}// 第一组凑齐了!head = end;		//以后head不动了reverse(start, end);// 上一组的结尾节点ListNode lastEnd = start;while (lastEnd.next != null) {start = lastEnd.next;end = getKGroupEnd(start, k);if (end == null) {return head;}reverse(start, end);lastEnd.next = end;lastEnd = start;}return head;}//设一个函数,给你开始节点,数够k个,把第k个返回public static ListNode getKGroupEnd(ListNode start, int k) {while (--k != 0 && start != null) {		//&前面--k!=0,指针往后走,&后面是不够k个返回空start = start.next;				//}return start;}
//public static void reverse(ListNode start, ListNode end) {end = end.next;	ListNode pre = null;ListNode cur = start;ListNode next = null;while (cur != end) {	//到end才停,所以第一步end先往后跳一格next = cur.next;cur.next = pre;pre = cur;cur = next;}start.next = end;}}


5.两个链表相加

package class04;// 测试链接:https://leetcode.com/problems/add-two-numbers/
public class Code05_AddTwoNumbers {// 不要提交这个类public static class ListNode {public int val;public ListNode next;public ListNode(int val) {this.val = val;}public ListNode(int val, ListNode next) {this.val = val;this.next = next;}}public static ListNode addTwoNumbers(ListNode head1, ListNode head2) {int len1 = listLength(head1);int len2 = listLength(head2);//长链表归l,短链表归sListNode l = len1 >= len2 ? head1 : head2;ListNode s = l == head1 ? head2 : head1;ListNode curL = l;ListNode curS = s;ListNode last = curL;int carry = 0;		//单独开一个,储存进位信息(0/1)int curNum = 0;while (curS != null) {	//第一阶段长链表短链表都有curNum = curL.val + curS.val + carry;	//当前位置的值curL.val = (curNum % 10);carry = curNum / 10;last = curL;	//last记录最后一个不空的节点(备份),直到第三阶段curL = curL.next;curS = curS.next;}while (curL != null) {	第二阶段,短链表没了curNum = curL.val + carry;curL.val = (curNum % 10);carry = curNum / 10;last = curL;curL = curL.next;}if (carry != 0) {	第二阶段,长短链表都没了last.next = new ListNode(1);}return l;	//把两个链表相加之后的结果覆盖到原来的长链表中,也可以在单独开一个链表储存相加之后的额结果}// 求链表长度public static int listLength(ListNode head) {int len = 0;while (head != null) {len++;head = head.next;}return len;}}

6.两个有序链表的合并

package class04;// 测试链接:https://leetcode.com/problems/merge-two-sorted-lists
public class Code06_MergeTwoSortedLinkedList {// 不要提交这个类public static class ListNode {public int val;public ListNode next;}public static ListNode mergeTwoLists(ListNode head1, ListNode head2) {if (head1 == null || head2 == null) {return head1 == null ? head2 : head1;}ListNode head = head1.val <= head2.val ? head1 : head2;	//小的做总头ListNode cur1 = head.next;ListNode cur2 = head == head1 ? head2 : head1;ListNode pre = head;while (cur1 != null && cur2 != null) {if (cur1.val <= cur2.val) {pre.next = cur1;	//pre的指向,谁小指谁cur1 = cur1.next;	//谁小谁往下走} else {pre.next = cur2;cur2 = cur2.next;}pre = pre.next;}pre.next = cur1 != null ? cur1 : cur2;return head;}}

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

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

相关文章

Java 字符串 05 练习-遍历字符串和统计字符个数

代码&#xff1a; import java.util.Scanner; public class practice{public static void main(String[] args) {//键盘录入一个字符串&#xff0c;并进行遍历&#xff1b;Scanner input new Scanner(System.in);System.out.println("输入一个字符串&#xff1a;")…

webassembly003 whisper.cpp的main项目-1

参数设置 /home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug/bin/main options:-h, --help [default] show this help message and exit-t N, --threads N [4 ] number of threads to use during computation-p N, --processors …

Android App开发-简单控件(2)——视图基础

2.2 视图基础 本节介绍视图的几种基本概念及其用法&#xff0c;包括如何设置视图的宽度和高度&#xff0c;如何设置视图的外部间距和内部间距&#xff0c;如何设置视图的外部对齐方式和内部对齐方式等等。 2.2.1 设置视图的宽高 手机屏幕是块长方形区域&#xff0c;较短的那…

【星海随笔】unix 启动问题记录.

启动Ubuntu操作系统时&#xff0c;直接进入GRUB状态。 调试时候&#xff0c;曾显示 no bootable device no known filesystem detected 注意&#xff1a; 目前 GRUB 分成 GRUB legacy 和 GRUB 2。版本号是 0.9x 以及之前的版本都称为 GRUB Legacy &#xff0c;从 1.x 开始的就称…

NODE笔记 2 使用node操作飞书多维表格

前面简单介绍了node与简单的应用&#xff0c;本文通过结合飞书官方文档 使用node对飞书多维表格进行简单的操作&#xff08;获取token 查询多维表格recordid&#xff0c;删除多行数据&#xff0c;新增数据&#xff09; 文章目录 前言 前两篇文章对node做了简单的介绍&#xff…

eNSP学习——配置通过STelnet登陆系统

目录 背景 实验内容 实验目的 实验步骤 实验拓扑 详细配置过程 基础配置 配置SSH server 配置SSH client 配置SFTP server 与client 背景 由于Telnet缺少安全的认证方式&#xff0c;而且传输过程采用的是TCP进行明文传输。单纯的提供Telnet服务容易招致主机IP地址欺骗、路…

数据分析 - 图形化解释(后续添加)

图形化解释 作为数据分析师来说一个好的图形&#xff0c;就是自己的数据表达能力 简单文本 只有一两项数据需要分享的时候&#xff0c;简单的文本是最佳的沟通方法 下图的对比可以看出来文字的表达效果会好很多 散点图 散点图在展示两件事的关系时很有用&#xff0c;观察是否存…

【搞懂设计模式】命令模式:从遥控器到编程的妙用!

我们都熟悉电视遥控器&#xff0c;它有许多按钮&#xff0c;每个按钮都有确定的功能。你按下电源键电视就会打开&#xff0c;再按下一次电视就会关闭。编程世界里也有这种模式&#xff0c;这就是我们说的命令模式。 命令模式是一种设计模式&#xff0c;它把一个请求或操作封装…

以梦为码,CodeArts Snap 缩短我与算法的距离

背景 最近一直在体验华为云的 CodeArts Snap&#xff0c;逐渐掌握了使用方法&#xff0c;代码自动生成的准确程度大大提高了。 自从上次跟着 CodeArts Snap 学习用 Python 编程&#xff0c;逐渐喜欢上了 Python。 我还给 CodeArts Snap 起了一个花名&#xff1a; 最佳智能学…

计算机服务器中了halo勒索病毒怎么办,halo勒索病毒解密处理流程

计算机技术的发展与应用为企业的生产生活提供了坚实基础&#xff0c;但同时也为网络安全威胁制造了有利条件。近期&#xff0c;网络上的勒索病毒非常嚣张&#xff0c;给企业的计算机服务器带来严重威胁。近日&#xff0c;云天数据恢复中心接到山东某制造公司的求助&#xff0c;…

Oracle DG环境下的秘钥管理

今天有朋友问到1&#xff09;DG环境下的秘钥管理需要注意什么&#xff0c;2&#xff09;秘钥管理对DG的日志同步有影响吗&#xff1f; 对于2&#xff09;的回答是明确的&#xff0c;没有影响。秘钥的管理和DG的redo log shipping完全是两套机制。在最新版的Oracle Key Vault常…

Qlik Sense : ErrorCode(错误变量)

错误变量 所有错误变量的值在脚本执行之后依然保留。第一个变量 ErrorMode 由用户输入&#xff0c;最后三个变量是 Qlik Sense 的输出&#xff08;包括脚本中错误的信息&#xff09;。 使用每个变量的下拉列表可查看每个变量的简短描述和语法。单击语法描述中的变量名称可了解…

Vulnhub靶机:FunBox10

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;FunBox10&#xff08;10.0.2.35&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://download.vulnhub.com/funbo…

Effective C++——关于重载赋值运算

令operator返回一个*this的引用 在重载,,*等运算符时&#xff0c;令其返回一个指向this的引用。 class MyClass {int* val; public:MyClass(int i) : val(new int(i)){}MyClass():val(new int(0)){}void print() {cout << *val << endl;}MyClass& operator(co…

LabVIEW电液比例阀测试系统

电液比例阀与普通阀和伺服阀相比&#xff0c;比例阀展现出显著的耐污染和可靠性特点。为了满足这些比例阀的综合性能测试需求&#xff0c;开发了一种基于LabVIEW软件的电液比例阀综合性能试验台。这个系统不仅能够进行比例压力阀、流量阀和方向阀的性能测试&#xff0c;而且通过…

RabbitMQ 笔记一

概览&#xff1a; MQ基本概念 RabbitMQ入门 基本工作模 1.MQ是什么&#xff1f; MQ:Message Queue, 存储消息的中间件&#xff0c;是消息发送过程中的暂存容器&#xff0c;主要用于解决分布式系统进程间的通信。 分布式系统通信的两种方式&#xff1a;直接远程调用、借助第三…

01:云计算底层技术奥秘|虚拟化管理|公有云概述

云计算底层技术奥秘&#xff5c;虚拟化管理&#xff5c;公有云概述 虚拟化平台安装验证虚拟化支持 Linux虚拟机创建虚拟机磁盘虚拟机配置文件创建虚拟机 公有云简介 虚拟化平台安装 虚拟化&#xff1a;是一种技术 就是将不可拆分的实体资源变成可以自由划分的逻辑资源&#xf…

one-stage/two-stage区别

One-stage和Two-stage是目标检测中的两种主要方法&#xff0c;它们在处理速度和准确性上存在显著差异。以下是两者的主要区别&#xff1a; 处理流程&#xff1a;One-stage方法通过卷积神经网络直接提取特征&#xff0c;并预测目标的分类与定位&#xff0c;一步到位&#xff0c…

【Go学习】Ginkgo测试框架学习实践 + 问题记录 + 怎么解决(0)

1、ginkgo测试框架介绍&#xff1a;https://onsi.github.io/ginkgo/ 2、重点是学习实践 问题记录 怎么解决 3、送福利&#xff1a;国内好用的ChatGpt有很多&#xff0c;比如&#xff1a;天工、文心一言、讯飞星火、通义万相等 1. 安装 xxxmacdeMacBook-Pro-3  /Volumes/mac…

【JS基础】定时器的使用、事件监听

文章目录 前言一、定时器1.1定时器是什么1.2 setInterval函数1.3 关闭定时器clearInterval 二、事件监听2.1 事件监听是什么2.2 事件监听的使用基本语法点击事件鼠标事件焦点事件键盘事件 2.3 事件对象event 总结 前言 JavaScript 中的定时器和事件监听是 Web 开发中至关重要的…