数据结构与算法(二)

文章目录

    • 数据结构与算法(二)
      • 1 时间复杂度、空间复杂度、排序算法和二分法
        • 1.1 简单的排序算法
        • 1.2 二分查找
      • 2 异或运算、进一步认识对数器的重要性
        • 2.1 不用额外变量交换两个数的值
        • 2.2 不用额外变量交换数组中两个数的值
        • 2.3 一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
        • 2.4 一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数
        • 2.5 一个数组中有一种数出现K次,其他数都出现了M次
      • 3 单双链表、栈和队列、递归和Master公式、哈希表和有序表的使用和性能
        • 3.1 反转单链表、反转双链表
        • 3.2 在链表中删除指定值的所有节点
        • 3.3 用双链表实现栈和队列
        • 3.4 用环形数组实现栈和队列
        • 3.5 实现有getMin功能的栈
        • 3.6 两个栈实现队列
        • 3.7 两个队列实现栈
        • 3.8 用递归行为得到数组中的最大值,并用master公式来估计时间复杂度
        • 3.9 哈希表和有序表使用的code展示
      • 4 归并排序及其常见面试题
        • 4.2 数组小和
        • 4.3 数组的降序对
        • 4.4 大于2倍问题
      • 5 归并排序面试题(续)、快速排序
        • 5.1 区间和的个数
        • 5.2 荷兰国旗问题
        • 5.3 快速排序从1.0到3.0的实现
        • 5.4 快速排序的非递归实现
        • 5.5 双向链表进行快速排序
      • 6 比较器、堆结构、堆排序
        • 6.1 比较器使用的code展示
        • 6.2 堆结构的实现
        • 6.3 堆排序的实现
        • 6.4 基本有序的数组
      • 7 和堆有关的面试题、加强堆结构
        • 7.1 线段最大重合问题
        • 7.2 加强堆的实现
        • 7.3 得奖系统
      • 8 前缀树、不基于比较的排序(计数排序、基数排序)、排序算法的稳定性
        • 8.1 前缀树实现
        • 8.2 计数排序
        • 8.3 基数排序
        • 8.4 排序算法的稳定性
        • 8.5 排序算法总结

数据结构与算法(二)

1 时间复杂度、空间复杂度、排序算法和二分法

  • 内容:
    • 评估算法优劣的核心指标
    • 时间复杂度、空间复杂度、估算方式、意义
    • 常数时间的操作
    • 选择排序、冒泡排序、插入排序
    • 最优解
    • 对数器
    • 二分法
1.1 简单的排序算法
  • 选择排序

image.png

  • 冒泡排序

image.png

  • 插入排序

image.png

1.2 二分查找
  • 有序数组中找到num

image.png

  • 有序数组中找到>=num最左的位置

image.png

  • 有序数组中找到<=num最右的位置

image.png

  • 局部最小值问题,定义何为局部最小值:
    • arr[0] < arr[1],0位置是局部最小;
    • arr[N-1] < arr[N-2],N-1位置是局部最小;
      arr[i-1] > arr[i] < arr[i+1],i位置是局部最小;
    • 给定一个数组arr,已知任何两个相邻的数都不相等,找到随便一个局部最小位置返回

image.png

2 异或运算、进一步认识对数器的重要性

  • 内容:
    • 异或运算的性质
    • 异或运算的题目
2.1 不用额外变量交换两个数的值
a = a ^ b;
b = a ^ b;
a = a ^ b;
2.2 不用额外变量交换数组中两个数的值
public static void swap (int[] arr, int i, int j) {arr[i]  = arr[i] ^ arr[j];arr[j]  = arr[i] ^ arr[j];arr[i]  = arr[i] ^ arr[j];
}
2.3 一个数组中有一种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这种数
  • arr数组中,只有一种数出现奇数次
public static void printOddTimesNum1(int[] arr) {int ans = 0;for (int x : arr) ans ^= x;System.out.println(ans);
}
2.4 一个数组中有两种数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两种数

怎么把一个int类型的数 x,提取出二进制中最右侧的1?

x & (~x + 1) 等价于 x & (-x)

public static void printOddTimesNum2(int[] arr) {int eor = 0;for (int i = 0; i < arr.length; i++) {eor ^= arr[i];}// a 和 b是两种数// eor != 0// eor最右侧的1,提取出来// eor :     00110010110111000// rightOne :00000000000001000int rightOne = eor & (-eor); // 提取出最右的1int onlyOne = 0; // eor'for (int i = 0 ; i < arr.length;i++) {//  arr[1] =  111100011110000// rightOne=  000000000010000if ((arr[i] & rightOne) != 0) {onlyOne ^= arr[i];}}System.out.println(onlyOne + " " + (eor ^ onlyOne));
}
2.5 一个数组中有一种数出现K次,其他数都出现了M次
  • 已知M > 1,K < M,找到出现了K次的数,要求额外空间复杂度O(1),时间复杂度O(N)
// 对数器 for test
public static int test(int[] arr, int k, int m) {Map<Integer, Integer> counter = new HashMap<>();for (int x : arr) {counter.compute(x, (key, v) -> v == null ? 1 : v + 1);}for (Integer num : counter.keySet()) {if (counter.get(num) == k) {return num;}}return -1;
}
public static int onlyKTimes(int[] arr, int k, int m) {int intBits = 32;int[] bitCounter = new int[intBits];// bitCounter[0]: 0 位置的1出现了几个// bitCounter[i]: i 位置的1出现了几个for (int x : arr) {for (int i = 0; i < intBits; i++) {//          if (((x >> i) & 1) != 0) {//             bitCounter[i] += 1;//          }bitCounter[i] += (x >> i) & 1;}}int ans = 0;for (int i = 0; i < intBits; i++) {if (bitCounter[i] % m != 0) {// 在第i位上有1ans |= (1 << i);}}return ans;
}

题目变一下,如果能找到出现K次的数,就返回该数;如果找不到,返回-1。

public static int onlyKTimes(int[] arr, int k, int m) {int intBits = 32;int[] bitCounter = new int[intBits];// bitCounter[0]: 0 位置的1出现了几个// bitCounter[i]: i 位置的1出现了几个for (int x : arr) {for (int i = 0; i < intBits; i++) {//				if (((x >> i) & 1) != 0) {//					bitCounter[i] += 1;//				}bitCounter[i] += (x >> i) & 1;}}int ans = 0;for (int i = 0; i < intBits; i++) {//			if (bitCounter[i] % m != 0) {//				// 在第i位上有1//				ans |= (1 << i);//			}// 题目变一下,如果能找到出现K次的数,就返回该数;如果找不到,返回-1。if (bitCounter[i] % m == 0) continue;if (bitCounter[i] % m == k) ans |= (1 << i);else return -1;}// 边界处理if (ans == 0) {int cnt = 0;for (int x : arr) {if (x == 0) cnt++;}if (cnt != k) return -1;}return ans;
}

3 单双链表、栈和队列、递归和Master公式、哈希表和有序表的使用和性能

  • 内容:
    • 单链表、双链表
    • 栈、队列
    • 递归的物理实质
    • 评估递归复杂度的Master公式
    • 哈希表的使用和性能
    • 有序表的使用和性能
3.1 反转单链表、反转双链表
  • 反转单链表
image.png
  • 反转双链表
image.png
3.2 在链表中删除指定值的所有节点
public static Node removeValue(Node head, int num) {// head来到第一个不需要删的位置while (head != null) {if (head.val != num) break;head = head.next;}// 1 ) head == null// 2 ) head != nullNode pre = head;Node cur = head;while (cur != null) {if (cur.val == num) pre.next = cur.next;else pre = cur;cur = cur.next;}return head;
}
3.3 用双链表实现栈和队列
  • 基于之前实现的双端队列 MyDeque 实现
public static class MyStack<T> {private MyDeque<T> queue;public MyStack() {queue = new MyDeque<>();}public void push(T value) {queue.pushHead(value);}public T pop() {return queue.pollHead();}public boolean isEmpty() {return queue.isEmpty();}
}public static class MyQueue<T> {private MyDeque<T> queue;public MyQueue() {queue = new MyDeque<>();}public void push(T value) {queue.pushHead(value);}public T poll() {return queue.pollTail();}public boolean isEmpty() {return queue.isEmpty();}
}
3.4 用环形数组实现栈和队列
public static class MyQueue {private int[] items;private int head;private int tail;private int size;private final int capacity;public MyQueue(int capacity) {this.items = new int[capacity];this.head = 0;this.tail = 0;this.size = 0;this.capacity = capacity;}public void push(int val) {if (isFull()) throw new RuntimeException("queue is full");size++;items[head] = val;head = resetOffset(head);}public int pop() {if (isEmpty()) throw new RuntimeException("queue is empty");size--;int item = items[tail];tail = resetOffset(tail);return item;}public boolean isEmpty() {return size == 0;}public boolean isFull() {return size == capacity;}private int resetOffset(int idx) {return idx < capacity - 1 ? idx + 1 : 0;} 
}
3.5 实现有getMin功能的栈
public static class MinStack {// 定义两个栈:一个数据栈(用于正常存放数据)、一个最小栈(用于存放栈中的最小值)private Stack<Integer> dataStack;private Stack<Integer> minStack;public MinStack() {dataStack = new Stack<>();minStack = new Stack<>();}public void push(int newVal) {dataStack.push(newVal);// 每次push新值时,同时维护最小栈minStack// minStack如果为空,则直接放进去;如果不为空,则比较当前栈顶最小值和新值,取小的minStack.push(minStack.isEmpty() ? newVal : Math.min(newVal, minStack.peek()));}public int pop() {if (dataStack.isEmpty()) throw new RuntimeException("MinStack is Empty");int val = dataStack.pop();// 每次pop时,比较是否是栈顶的最小值,如果是,则minStack也需要出栈if (val == minStack.peek()) minStack.pop();return val;}public int getMin() {if (minStack.isEmpty()) throw new RuntimeException("MinStack is Empty");return minStack.peek();}
}
3.6 两个栈实现队列
public static class StackQueue<T> {// 定义两个栈:一个push栈(作为队列头部加数据)、一个pop栈(作为队列尾部取数据)private Stack<T> pushStack;private Stack<T> popStack;public StackQueue() {this.pushStack = new Stack<>();this.popStack = new Stack<>();}public void add(T val) {pushStack.push(val);// 每次添加数据时,同时维护pop栈popStack// popStack为空时,才将pushStack中的数据导入到popStackrebalance();}public T remove() {if (isEmpty()) throw new RuntimeException("StackQueue is empty");// 每次移除数据时,同时维护pop栈popStackrebalance();return popStack.pop();}public T peek() {if (isEmpty()) throw new RuntimeException("StackQueue is empty");// 每次查看数据时,同时维护pop栈popStackrebalance();return popStack.peek();}private void rebalance() {if (!popStack.isEmpty()) return;while (!pushStack.isEmpty()) popStack.push(pushStack.pop());}private boolean isEmpty() {return popStack.isEmpty() && pushStack.isEmpty();}
}
3.7 两个队列实现栈
public static class QueueStack<T> {// 定义两个队列:一个用于入栈、出栈,一个用于来回倒数据private Queue<T> queue;private Queue<T> help;public QueueStack() {this.queue = new LinkedList<>();this.help = new LinkedList<

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

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

相关文章

读写分离MySQL

利用Mycat控制后台数据库的读写分离和负载均衡 利用主从复制思想,实现读写分离,主库写,从库读 从库最好不要写,因为从库写入的数据不能同步到主库,只有主库写的数据才能同步到从库 balance属性值对应的含义(负载均衡) 一主一从读写分离的弊端 主节点Master宕机以后,业务系统…

docker 操作redis

1查看容器 2进入容器 exec表示在运行的容器中执行命令it表示以终端交互的方式执行命令/bin/bash表示需要指定的命令 3进入容器后可通过redis-cli命令连接容器内的redis服务器&#xff0c;可通过set创建变量&#xff0c;get获取变量的值 4key * 查看所有key 通过ping 查看redi…

【深度学习实验】前馈神经网络(final):final

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 构建数据集&#xff08;IrisDataset&#xff09; 2. 构建模型&#xff08;FeedForward&#xff09; a. __init__(初始化) b. forward(前向传播) 3.整合训练、评估…

golang优先级坑

看如下代码&#xff0c;我本以为a1, a2是相同的 package mainimport "fmt"func main() {b, c, d : 1, 0, 1a1 : b ^ c&(^d) // 1 ^a2 : c ^ b&(^d) // 0 ^fmt.Println(a1, a2) // 1 0 }但结果却是不同的&#xff0c;在golang中&的优先级^和&#xff5c;…

罗德里格斯公式

1.点乘 A ⃗ ⋅ B ⃗ ∣ A ⃗ ∣ ∣ B ⃗ ∣ c o s ⟨ A ⃗ , B ⃗ ⟩ \vec{A} \cdot \vec{B} \left | \vec{A} \right | \left | \vec{B} \right | cos\left \langle \vec{A}, \vec{B} \right \rangle A ⋅B ​A ​ ​B ​cos⟨A ,B ⟩ 对应几何意义&#xff1a;向量 A ⃗…

众佰诚:抖音店铺开网店前期需要投入多少

随着互联网的迅猛发展&#xff0c;电子商务已经成为了商业领域中的一股不可忽视的力量。而在电子商务中&#xff0c;抖音店铺已经成为了一个备受关注的平台&#xff0c;吸引了众多创业者和商家的关注。那么&#xff0c;在开设抖音店铺并转型为网店之前&#xff0c;究竟需要投入…

SVN的基本使用

一、SVN介绍 SVN&#xff08;Subversion&#xff09;是一个开源的版本控制系统&#xff0c;它专门用于管理文件和目录的变更。SVN 提供了一种集中式的版本控制方案&#xff0c;其中有一个中央仓库存储所有文件的历史记录和变更。 SVN使用方式相对简单&#xff0c;可以通过命令…

ROS 基础教程

欢迎访问我的博客首页。 ROS 基础教程 1.urdf 文件1.1 在 Rviz 中显示 urdf1.1.1 定义 urdf1.1.2 在 Rviz 中查看 urdf 1.2 在 Gazebo 中显示 urdf1.2.1 定义 urdf1.2.2 在 Gazebo 中查看 urdf 2.建图-仿真2.1 模型 1.urdf 文件 假设我们的工作空间是 ws_ros。我们自己实现的包…

有效保护敏感数据的最佳实践

在当今数据驱动的环境中&#xff0c;数据就是力量&#xff0c;组织仍然高度关注如何利用其数据进行 BI、分析和其他业务驱动计划。 事实上&#xff0c;最近的研究表明&#xff0c;数据领导者的主要动机是对高质量分析洞察的需求&#xff0c;而不是合规性。 然而&#xff0c;…

Centos7原生hadoop环境,搭建Impala集群和负载均衡配置

Centos7原生hadoop环境&#xff0c;搭建Impala集群和负载均衡配置 impala介绍 Impala集群包含一个Catalog Server (Catalogd)、一个Statestore Server (Statestored) 和若干个Impala Daemon (Impalad)。Catalogd主要负责元数据的获取和DDL的执行&#xff0c;Statestored主要负…

greenhills compiler 2021.1.4 for x86 Linux

greenhills compiler 2021.1.4 for x86 Linux 2692407267qq.com&#xff0c;更多内容请见http://user.qzone.qq.com/2692407267/

ipad触控笔有必要买原装吗?ipad2023手写笔推荐

目前&#xff0c;在无纸教学、无纸办公的大背景下&#xff0c;电容笔得到了广泛的关注。只是&#xff0c;对于这两支电容笔的不同之处&#xff0c;不少人并不是很清楚。其实这两种电容笔都很好区分&#xff0c;第一种是主动电容笔&#xff0c;也就是我们常用的电容式屏幕&#…

JavaWeb开发-06-SpringBootWeb-MySQL

一.MySQL概述 1.安装、配置 官网下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 2.数据模型 3.SQL简介 二.数据库设计-DDL 1.数据库 官网&#xff1a;http:// https://www.jetbrains.com/zh-cn/datagrip/ 2.表&#xff08;创建、查询、修改、删除&#xff09; #…

前端react 18.2整合ckeditor富文本编辑器——配置插件、自定义toolbar工具栏

文章目录 ⭐前言⭐引入ckeditor⭐npm 包引入⭐cdn资源引入 ⭐自定义插件&#x1f496; 自定义yma16配置插件 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于前端react整合ckeditor——配置插件、自定义toolbar工具栏。 react系列往期文章&#xff…

SpringBoot使用@Async异步注解

首先&#xff0c;想一想为什么使用异步线程? 举个例子: 当我们请求这个接口的时候,在接口调用了method这个方法 然而被调用的方法执行了一个线程睡眠三秒 因为method方法睡眠了三秒钟,所以这个接口响应的时间肯定是大于三秒。因为接口是从上往下执行的,首先会在控制台输出一…

UE5读取json文件

一、下载插件 在工程中启用 二、定义读取外部json文件的函数&#xff0c;参考我之前的文章 ue5读取外部文件_艺菲的博客-CSDN博客 三、读取文件并解析为json对象 这里Load Text就是自己定义的函数&#xff0c;ResourceBundle为一个字符串常量&#xff0c;通常是读取的文件夹…

Super Marker插件——标记资源,提高效率

插件介绍&#xff1a; 这是一款可以给资源添加颜色或图标标记&#x1f4cc;的插件&#xff0c;当资源文件比较多的时候&#xff0c;颜色标记可以让你一眼定位到要使用的资源&#xff0c;提高开发效率。 插件地址&#xff1a; Cocos商店&#xff1a;https://store.cocos.com/a…

nginx SseEmitter 长连接

1、问题还原&#xff1a; 在做openai机器人时&#xff0c;后台使用 SseEmitterEventSource 实现流式获取数据&#xff0c;前端通过 EventSourcePolyfill 函数接收后端的数据&#xff0c;在页面流式输出到页面&#xff0c;做成逐字打稿的效果。本地测试后&#xff0c;可以正常获…

如何用好免费的ChatGPT

如何用好免费的ChatGPT 前言ChatGPT使用入口在线体验地址&#xff1a;点我体验 ChatGPT介绍ChatGPT初级使用技巧初级使用技巧&#xff1a;清晰明了的问题表达 ChatGPT中级使用语法中级使用语法&#xff1a;具体化问题并提供背景信息 ChatGPT高级使用高级使用&#xff1a;追问、…

python随手小练3

题目&#xff1a; 写出一个判断闰年的python代码&#xff1a; 闰年的条件&#xff1a; 如果N能够被4整除&#xff0c;并且不能被100整除&#xff0c;则是闰年 或者&#xff1a;N能被400整除&#xff0c;也是闰年 即&#xff1a;4年一润并且百年不润&#xff0c;每400年再润一…