常见の算法链表问题

时间复杂度

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 …

C++(一) 类之封装

类的介绍 类的三大特性&#xff1a;封装 继承 多态 类是在结构体的基础上进化而来 类由成员变量&#xff08;属于对象&#xff09;&#xff0c;成员方法&#xff08;属于类&#xff09;构成 创建对象时开辟的空间是用来存储成员变量的 成员方法是属于类的&#xff0c;不属…

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

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

【Python基础015】集合的用法

1、定义 集合是无序可变&#xff0c;元素不能重复。实际上&#xff0c;集合底层是字典实现&#xff0c;集合的所有元素都是字典中的 “ 键对象”&#xff0c;因此是不能重复的且唯一的。 2、创建 &#xff08;1&#xff09;使用{}创建 a {1, 2, 3} # 集合存储整数b {1, 2,…

【星海随笔】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地址欺骗、路…

nicegui 万能布局

nicegui 万能布局 万能布局代码解析万能布局代码 from nicegui import ui from niceguiToolkit.layout import inject_layout_tool # import扩展库# 可视化调整样式 布局 inject_layout_tool() # 基本功能说明 # 可以加载 (这个是一个默认路径) 改变路径就是加载其他的文件…

【微信小程序】wxs脚本

1. 什么是 WXS WXS &#xff08; WeiXin Script &#xff09;是小程序独有的一套脚本语言&#xff0c;结合 WXML &#xff0c;可以构建出页面的结构。2. WXS 的应用场景 wxml 中无法调用在页面的 .js 中定义的函数&#xff08;不包括事件绑定&#xff09;&#xff0c;但是&am…

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

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

5.rk3588用cv读取图片(C++)

rk3588自带了cv&#xff0c;不需要重新安装&#xff0c;执行以下操作即可&#xff1a; 一、读取图片 1.读取某张图片 #define HAVE_OPENCV_VIDEO #define HAVE_OPENCV_VIDEOIO#include <opencv2/opencv.hpp> #include <iostream> #include <opencv2/opencv.h…

网络协议基础

tcp/ip协议簇 TCP/IP协议族 网络接口层(没有特定的协议) 物理层 数据链路层 网络层: IP (v4/v6) ARP(地址解析协议) RARP . ICMP (Internet控制报文协议) IGMP 传输层: TCP (传输控制协议) UDP (用户数据报协议) 应用层: 都是基于传输层协议的端口&#xff0c;总共端口0~65535 …

golang 实现协程池

go 的 goroutine 提供了一种比线程而言更廉价的方式处理并发场景。相比线程&#xff0c;协程占据更小的内存空间&#xff0c;并且由于是在用户态进行调度&#xff0c;上下文切换的代价更小。所以协程更加容易支撑几万几百万的并发。但 goroutine 太多仍会导致调度性能下降、GC …

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

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

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

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

千问 qwen7B 微调后的模型推理代码

watch -n 1 nvidia-smi 1、数据处理代码 import asttrain_dataset []# 定义合法的字段列表 valid_fields ["id", "conversations"]with open(train.json, r, encoding"utf-8") as f:train_data f.readlines() for i, item in enumerate(tra…

计算机服务器中了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;。 使用每个变量的下拉列表可查看每个变量的简短描述和语法。单击语法描述中的变量名称可了解…