算法笔记—链表、队列和栈

news2024/12/23 22:22:57

链表、队列和栈

  • 1. 链表
    • 1.1 单链表反转
    • 1.2 双链表反转
    • 1.3 合并两个有序链表
    • 1.4 链表相加
    • 1.5 划分链表
  • 2. 队列和栈
    • 2.1 循环队列
    • 2.2 栈实现队列
    • 2.3 队列实现栈
    • 2.4 最小栈
    • 2.2 双端队列

1. 链表

1.1 单链表反转

  • 力扣 反转链表
	// 反转单链表
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode next = null;
        while (head != null) {
            next = head.next;	// next指向head.next指的位置
            head.next = pre;	// head.next指向pre指向的位置
            pre = head;			// pre指向head指向的位置
            head = next;		// head指向next指向的位置
        }
        return pre;
    }

	// 单链表节点定义
	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;
		}
	}

1.2 双链表反转

	// 反转双链表
	public static DoubleListNode reverseDoubleList(DoubleListNode head) {
		DoubleListNode pre = null;
		DoubleListNode next = null;
		while (head != null) {
			next = head.next;
			head.next = pre;
			head.last = next;// 同时修改last指针即可
			pre = head;
			head = next;
		}
		return pre;
	}

	// 双链表节点
	public static class DoubleListNode {
		public int value;
		public DoubleListNode last;
		public DoubleListNode next;
		public DoubleListNode(int v) {
			value = v;
		}
	}

1.3 合并两个有序链表

  • 力扣链接
	// 合并两个有序链表
	public 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; 

        // 只要都没完 谁小谁挂在pre之后
        while (cur1 != null && cur2 != null) {
            if (cur1.val <= cur2.val) {
                pre.next = cur1;
                cur1 = cur1.next;
            } else {
                pre.next = cur2;
                cur2 = cur2.next;
            }
            pre = pre.next;
        }
        // 若有一个链表结束 另一个剩余的挂在pre之后
        pre.next = cur1 != null ? cur1 : cur2; //剩余部分
        return head;
    }

1.4 链表相加

力扣 两数相加

给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。

  • 请你将两个数相加,并以相同形式返回一个表示和的链表。
  • 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
    在这里插入图片描述
	// 链表两数相加 没有复用老链表
    public ListNode addTwoNumbers(ListNode h1, ListNode h2) {
        ListNode ans = null, cur = null; // 初始化新链表
        int carry = 0; // 进位数 加法的进位只能为 0 或者 1
        for (int sum, val; // 声明变量
             h1 != null || h2 != null; // 循环条件
             h1 = h1 == null ? null : h1.next, // 每一轮h1的跳转
             h2 = h2 == null ? null : h2.next  // 每一轮h2的跳转
        ) {
        
            sum = (h1 == null ? 0 : h1.val)
                    + (h2 == null ? 0 : h2.val)
                    + carry; // 上一轮的进位
            
            // 组建新链表
            val = sum % 10; // 个位
            carry = sum / 10; // 进位
            if (ans == null) {
                ans = new ListNode(val);
                cur = ans;
            } else {
                cur.next = new ListNode(val);
                cur = cur.next;
            }
        }
        // 判断最后一位有无进位  若有则挂 1 节点
        if (carry == 1) {
            cur.next = new ListNode(1);
        }
        return ans;
    }

1.5 划分链表

力扣 分隔链表

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

  • 你应当 保留 两个分区中每个节点的初始相对位置。
	public static ListNode partition(ListNode head, int x) {
        ListNode leftHead = null, leftTail = null;
        ListNode rightHead = null, rightTail = null;
        ListNode next = null;

        // 终止条件
        while (head != null) {
            next = head.next; //记录一下下一位置 因为要断链
            head.next = null;
            // 小于范围
            if (head.val < x) {
                // set head
                if (leftHead == null) {
                    leftHead = head;
                } else {
                    leftTail.next = head;
                }
                // set tail
                leftTail = head;
            // 大于范围
            } else {
                if (rightHead == null) {
                    rightHead = head;
                } else {
                    rightTail.next = head;
                }
                rightTail = head;
            }
            head = next; // 处理下一节点
        }
        // 默认返回左头 这里对左头进行判断
        // 如果没有小于的 直接返回右头结点
        if (leftHead == null){
            return rightHead;
        }
        leftTail.next = rightHead;
        return leftHead;
    }
	// 单链表节点
    public static class ListNode {
        public int val;
        public Video_012.ListNode next;
        public ListNode(int val) {
            this.val = val;
        }
    	public ListNode(int val, Video_012.ListNode next) {
        	this.val = val;
        	this.next = next;
        }
    }

2. 队列和栈

2.1 循环队列

力扣 设计循环队列

class MyCircularQueue {
    public int[] queue;
    public int l, r, size, limit;

    // 同时在队列里的数字个数,不要超过k
    public MyCircularQueue(int k) {
        queue = new int[k];
        l = r = size = 0;
        limit = k;
    }
    
    public boolean enQueue(int value) {
        if (isFull()) {
            return false;
        } else {
            queue[r] = value;
            // r++, 结束了,跳回0
            r = r == limit - 1 ? 0 : (r + 1);
            size++;
            return true;
        }
    }
    
    public boolean deQueue() {
        if (isEmpty()) {
            return false;
        } else {
            // l++, 结束了,跳回0
            l = l == limit - 1 ? 0 : (l + 1);
            size--;
            return true;
        }
    }
    
    public int Front() {
        if (isEmpty()) {
            return -1;
        } else {
            return queue[l];
        }
    }
    
    public int Rear() {
        if (isEmpty()) {
            return -1;
        } else {
            int last = r == 0 ? (limit - 1) : (r - 1);
            return queue[last];
        }
    }
    
    public boolean isEmpty() {
        return size == 0;
    }
    
    public boolean isFull() {
        return size == limit;
    }
}

2.2 栈实现队列

力扣

class MyQueue {

    public Stack<Integer> in;

    public Stack<Integer> out;

    public MyQueue() {
        in = new Stack<Integer>();
        out = new Stack<Integer>();
    }

    // 倒数据
    // 从in栈,把数据倒入out栈
    // 1) out空了,才能倒数据
    // 2) 如果倒数据,in必须倒完
    private void inToOut() {
        if (out.empty()) {
            while (!in.empty()) {
                out.push(in.pop());
            }
        }
    }

    public void push(int x) {
        in.push(x);
        inToOut();
    }

    public int pop() {
        inToOut();
        return out.pop();
    }

    public int peek() {
        inToOut();
        return out.peek();
    }

    public boolean empty() {
        return in.isEmpty() && out.isEmpty();
    }
}

2.3 队列实现栈

力扣

class MyStack {

    Queue<Integer> queue;

    public MyStack() {
        queue = new LinkedList<Integer>();
    }

    // O(n)
    public void push(int x) {
        int n = queue.size();
        queue.offer(x);
        for (int i = 0; i < n; i++) {
            queue.offer(queue.poll());
        }
    }

    public int pop() {
        return queue.poll();
    }

    public int top() {
        return queue.peek();
    }

    public boolean empty() {
        return queue.isEmpty();
    }
}

2.4 最小栈

力扣

class MinStack {
    public final int MAXN = 8001;
    public int[] data;
    public int[] min;
    int size;

    public MinStack() {
        data = new int[MAXN];
        min = new int[MAXN];
        size = 0;
    }

    public void push(int val) {
        data[size] = val;
        if (size == 0 || val <= min[size - 1]) {
            min[size] = val;
        } else {
            min[size] = min[size - 1];
        }
        size++;
    }

    public void pop() {
        size--;
    }

    public int top() {
        return data[size - 1];
    }

    public int getMin() {
        return min[size - 1];
    }
}

2.2 双端队列

力扣 设计循环双端队列

	// 双向链表实现
	// 常数操作慢,但是leetcode数据量太小了,所以看不出劣势
	class MyCircularDeque {

		public Deque<Integer> deque = new LinkedList<>();
		public int size;
		public int limit;

		public MyCircularDeque1(int k) {
			size = 0;
			limit = k;
		}

		public boolean insertFront(int value) {
			if (isFull()) {
				return false;
			} else {
				deque.offerFirst(value);
				size++;
				return true;
			}
		}

		public boolean insertLast(int value) {
			if (isFull()) {
				return false;
			} else {
				deque.offerLast(value);
				size++;
				return true;
			}
		}

		public boolean deleteFront() {
			if (isEmpty()) {
				return false;
			} else {
				size--;
				deque.pollFirst();
				return true;
			}
		}

		public boolean deleteLast() {
			if (isEmpty()) {
				return false;
			} else {
				size--;
				deque.pollLast();
				return true;
			}
		}

		public int getFront() {
			if (isEmpty()) {
				return -1;
			} else {
				return deque.peekFirst();
			}
		}

		public int getRear() {
			if (isEmpty()) {
				return -1;
			} else {
				return deque.peekLast();
			}
		}

		public boolean isEmpty() {
			return size == 0;
		}

		public boolean isFull() {
			return size == limit;
		}

	}
	// 用数组实现,常数操作快
	// 但是leetcode数据量太小了,看不出优势
	class MyCircularDeque {
		public int[] deque;
		public int l, r, size, limit;
		
		public MyCircularDeque2(int k) {
			deque = new int[k];
			l = r = size = 0;
			limit = k;
		}

		public boolean insertFront(int value) {
			if (isFull()) {
				return false;
			} else {
				if (isEmpty()) {
					l = r = 0;
					deque[0] = value;
				} else {
					l = l == 0 ? (limit - 1) : (l - 1);
					deque[l] = value;
				}
				size++;
				return true;
			}
		}

		public boolean insertLast(int value) {
			if (isFull()) {
				return false;
			} else {
				if (isEmpty()) {
					l = r = 0;
					deque[0] = value;
				} else {
					r = r == limit - 1 ? 0 : (r + 1);
					deque[r] = value;
				}
				size++;
				return true;
			}
		}

		public boolean deleteFront() {
			if (isEmpty()) {
				return false;
			} else {
				l = (l == limit - 1) ? 0 : (l + 1);
				size--;
				return true;
			}
		}

		public boolean deleteLast() {
			if (isEmpty()) {
				return false;
			} else {
				r = r == 0 ? (limit - 1) : (r - 1);
				size--;
				return true;
			}
		}

		public int getFront() {
			if (isEmpty()) {
				return -1;
			} else {
				return deque[l];
			}
		}

		public int getRear() {
			if (isEmpty()) {
				return -1;
			} else {
				return deque[r];
			}
		}

		public boolean isEmpty() {
			return size == 0;
		}

		public boolean isFull() {
			return size == limit;
		}
	}

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

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

相关文章

达索系统SOLIDWORKS 2024 Visualize新功能

SOLIDWORKS Visualize&#xff08;原名为 Bunkspeed&#xff09;是一整套独立的软件工具&#xff0c;Visualize模块主要是用于对SOLIDWORKS设计出的产品图进行渲染、做动画&#xff0c;方便用户更好的展示、宣传产品&#xff1b;以最快速、最轻松的方式创建专业的照片级图像、动…

〖大前端 - 基础入门三大核心之JS篇(53)〗- 构造函数与类

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

【论文阅读笔记】M3Care: Learning with Missing Modalities in Multimodal Healthcare Data

本文介绍了一种名为“MCare”的模型&#xff0c;旨在处理多模态医疗保健数据中的缺失模态问题。这个模型是端到端的&#xff0c;能够补偿病人缺失模态的信息&#xff0c;以执行临床分析。MCare不是生成原始缺失数据&#xff0c;而是在潜在空间中估计缺失模态的任务相关信息&…

【知识积累】深度度量学习综述

原文指路&#xff1a;https://hav4ik.github.io/articles/deep-metric-learning-survey Problem Setting of Supervised Metric Learning 深度度量学习是一组旨在衡量数据样本之间相似性的技术。 Contrastive Approaches 对比方法的主要思想是设计一个损失函数&#xff0c;直…

STM32——震动传感器点亮LED灯

震动传感器简单介绍 若产品不震动&#xff0c;模块上的 DO 口输出高电平&#xff1b; 若产品震动&#xff0c;模块上的 DO 口输出低电平&#xff0c;D0-LED绿色指示灯亮。 震动传感器与STM32的接线 编程实现 需求&#xff1a;当震动传感器接收到震动信号时&#xff0c;使用中断…

Ubuntu 22安装PHP环境

参考博客为《练习 0&#xff08;2/2&#xff09;&#xff1a;Ubuntu 环境下安装PHP&#xff08;PHP-FPM&#xff09;》和《原生态Ubuntu部署LAMP环境 PHP8.1MySQLApache》 sudo apt-get install -y php7.4想要安装php7.4&#xff0c;发现安装的是php8.1。 完成如下图&#xf…

构思3年,巨 TM 好用的 localStorage 封装!!!

localStorage 和 sessionStorage 作为一个本地存储方案&#xff0c;所有的操作都是同步的&#xff0c;用法也非常简单&#xff0c;所以深受广大前端的喜爱。 但是由于 localStorage 只能存储字符串&#xff0c;所以存储其他数据就比较麻烦。比如我们要存储一个对象的话可能需要…

【程序人生】还记得当初自己为什么选择计算机?

✏️ 初识计算机&#xff1a; 还记得人生中第一次接触计算机编程是在高中&#xff0c;第一门编程语言是Python&#xff08;很可惜由于条件限制的原因&#xff0c;当时没能坚持学下去......现在想来有点后悔&#xff0c;没能坚持&#xff0c;唉......&#xff09;。但是&#xf…

STM32G030C8T6:使用外部晶振配置LED灯闪烁

本专栏记录STM32开发各个功能的详细过程&#xff0c;方便自己后续查看&#xff0c;当然也供正在入门STM32单片机的兄弟们参考&#xff1b; 本小节的目标是&#xff0c;使用STM32G030C8T6单片机&#xff0c;通过STM32CubeMX软件&#xff0c;配置并使用外部8MHz晶振&#xff0c;实…

python:五种算法(PSO、RFO、HHO、WOA、GWO)求解23个测试函数(python代码)

一、五种算法简介 1、粒子群优化算法PSO 2、红狐优化算法RFO 3、哈里斯鹰优化算法HHO 4、鲸鱼优化算法WOA 5、灰狼优化算法GWO 二、5种算法求解23个函数 &#xff08;1&#xff09;23个函数简介 参考文献&#xff1a; [1] Yao X, Liu Y, Lin G M. Evolutionary program…

git自动更新功能

确认权限 因为一般Linux系统网页用的www 或 www-data用户和用户组&#xff0c;所以要实现自动来去&#xff0c;首先要在www用户权限下生成ssh密钥&#xff0c;不然没有权限&#xff0c;其次就是&#xff0c;要把用root用户拉去的代码&#xff0c;批量改成www用户 1. 给www权…

Scrapy爬虫学习

Scrapy爬虫学习一 1 scrapy框架1.1 scrapy 是什么1.2 安装scrapy 2 scrapy的使用2.1创建scrapy项目2.2 创建爬虫文件2.3爬虫文件的介绍2.4 运行爬虫文件 3 爬取当当网前十页数据3.1 dang.py&#xff1a;爬虫的主文件3.2 items.py 定义数据结构3.3 pipelines.py 管道3.4 执行命令…

【教学类-06-16】20231213 (按比例抽题+乱序or先加再减后乘)X-Y之间“加法减法乘法+-×混合题”

作品展示&#xff1a; 背景需求&#xff1a; 大三班的“第一高手”对我提供的每一套的题目都只有一种反应&#xff1a; “这个是分合题&#xff0c;太简单了” “乘法&#xff0c;乘法我也会&#xff0c;11的1 22的4 33的9&#xff0c;,44十六……” “都太简单了&#xff0…

7个常见的jmeter压测问题

根据在之前的压测过程碰到的问题&#xff0c;今天稍微总结总结&#xff0c;以后方便自己查找。 一、单台Mac进行压测时候&#xff0c;压测客户端Jmeter启动超过2000个线程&#xff0c;Jmeter报OOM错误&#xff0c;如何解决&#xff1f; 解答&#xff1a;单台Mac配置内存为8G&…

快速上手linux | 一文秒懂Linux各种常用目录命令(上)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 一 、命令提示符和命令的基本格式1.1 如何查看主机名称及修改 二、命令基本格式2.1 命令格式示例2.2 参数的作用…

【价值几十万的仿抖音直播电商系统源码共享】

当下&#xff0c;传统的图文电商模式已经走向没落&#xff0c;以抖音为首的直播电商模式备受用户追捧&#xff0c;它具有实时直播和强互动的特点&#xff0c;是传统电商所不具备的优势。而且&#xff0c;当前正是直播电商的红利期&#xff0c;很多主播和品牌商都通过直播电商业…

【LeetCode刷题】-- 163.缺失的区间

163.缺失的区间 class Solution {public List<List<Integer>> findMissingRanges(int[] nums, int lower, int upper) {List<List<Integer>> res new ArrayList<>();for(int num : nums){if(lower < num){res.add(Arrays.asList(lower,num -…

华为OD试题二(文件目录大小、相对开音节、找最小数)

1. 文件目录大小 题目描述&#xff1a; 一个文件目录的数据格式为&#xff1a;目录id&#xff0c;本目录中文件大小&#xff0c;(子目录id 列表)。其中目录id全局唯一&#xff0c;取值范围[1,200]&#xff0c;本目录中文件大小范 围[1,1000]&#xff0c;子目录id列表个数[0,10…

考试的最大困扰度

说在前面 &#x1f388;不知道大家对于算法的学习是一个怎样的心态呢&#xff1f;为了面试还是因为兴趣&#xff1f;不管是出于什么原因&#xff0c;算法学习需要持续保持。 1、题目描述 一位老师正在出一场由 n 道判断题构成的考试&#xff0c;每道题的答案为 true &#xff…

每日一题,杨辉三角

给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: [[1]]