【数据结构与算法】(16)基础算法 之哈希表 相关示例 详细代码讲解

目录

    • 3.6 哈希表
      • 第一版
      • 生成 hashCode
      • 思考
      • 习题
        • E01. 两数之和-Leetcode 1
        • E02. 无重复字符的最长字串-Leetcode 3
        • E03. 字母异位词分组-Leetcode 49
        • E04. 判断有没有重复元素-Leetcode 217
        • E05. 找出出现一次的数字-Leetcode 136
        • E06. 判断字母异位词-Leetcode 242
        • E07. 第一个不重复字符-Leetcode 387
        • E08. 出现次数最多的单词-Leetcode 819
        • E09. 根据前序与中序遍历结果构造二叉树-Leetcode105 Improved
        • E10. 根据中序与后序遍历结果构造二叉树-Leetcode106 Improved

在这里插入图片描述

3.6 哈希表

第一版

未考虑 hash 码的生成,假定该 hash 码由我们提供

public class HashTable {// 节点类static class Entry {int hash; // 哈希码Object key; // 键Object value; // 值Entry next;public Entry(int hash, Object key, Object value) {this.hash = hash;this.key = key;this.value = value;}}Entry[] table = new Entry[16];int size = 0; // 元素个数float loadFactor = 0.75f; // 12 阈值int threshold = (int) (loadFactor * table.length);/* 求模运算替换为位运算- 前提:数组长度是 2 的 n 次方- hash % 数组长度 等价于 hash & (数组长度-1)*/// 根据 hash 码获取 valueObject get(int hash, Object key) {int idx = hash & (table.length - 1);if (table[idx] == null) {return null;}Entry p = table[idx];while (p != null) {if (p.key.equals(key)) {return p.value;}p = p.next;}return null;}// 向 hash 表存入新 key value,如果 key 重复,则更新 valuevoid put(int hash, Object key, Object value) {int idx = hash & (table.length - 1);if (table[idx] == null) {// 1. idx 处有空位, 直接新增table[idx] = new Entry(hash, key, value);} else {// 2. idx 处无空位, 沿链表查找 有重复key更新,否则新增Entry p = table[idx];while (true) {if (p.key.equals(key)) {p.value = value; // 更新return;}if (p.next == null) {break;}p = p.next;}p.next = new Entry(hash, key, value); // 新增}size++;if (size > threshold) {resize();}}private void resize() {Entry[] newTable = new Entry[table.length << 1];for (int i = 0; i < table.length; i++) {Entry p = table[i]; // 拿到每个链表头if (p != null) {/*拆分链表,移动到新数组,拆分规律* 一个链表最多拆成两个* hash & table.length == 0 的一组* hash & table.length != 0 的一组p0->8->16->24->32->40->48->nulla0->16->32->48->nullb8->24->40->null*/Entry a = null;Entry b = null;Entry aHead = null;Entry bHead = null;while (p != null) {if ((p.hash & table.length) == 0) {if (a != null) {a.next = p;} else {aHead = p;}a = p; // 分配到a} else {if (b != null) {b.next = p;} else {bHead = p;}b = p; // 分配到b}p = p.next;}// 规律: a 链表保持索引位置不变,b 链表索引位置+table.lengthif (a != null) {a.next = null;newTable[i] = aHead;}if (b != null) {b.next = null;newTable[i + table.length] = bHead;}}}table = newTable;threshold = (int) (loadFactor * table.length);}// 根据 hash 码删除,返回删除的 valueObject remove(int hash, Object key) {int idx = hash & (table.length - 1);if (table[idx] == null) {return null;}Entry p = table[idx];Entry prev = null;while (p != null) {if (p.key.equals(key)) {// 找到了, 删除if (prev == null) { // 链表头table[idx] = p.next;} else { // 非链表头prev.next = p.next;}size--;return p.value;}prev = p;p = p.next;}return null;}
}

生成 hashCode

在这里插入图片描述

hash 算法是将任意对象,分配一个编号的过程,其中编号是一个有限范围内的数字(如 int 范围内)

在这里插入图片描述

Object.hashCode

  • Object 的 hashCode 方法默认是生成随机数作为 hash 值(会缓存在对象头当中)
  • 缺点是包含相同的不同对象,他们的 hashCode 不一样,不能够用 hash 值来反映对象的特征,因此诸多子类都会重写 hashCode 方法

String.hashCode

public static void main(String[] args) {String s1 = "bac";                     String s2 = new String("abc");         System.out.println(s1.hashCode());System.out.println(s2.hashCode());// 原则:值相同的字符串生成相同的 hash 码, 尽量让值不同的字符串生成不同的 hash 码/*对于 abc  a * 100 + b * 10 + c对于 bac  b * 100 + a * 10 + c*/int hash = 0;for (int i = 0; i < s1.length(); i++) {char c = s1.charAt(i);System.out.println((int) c);// (a*10 + b)*10 + c  ==>  a*100 + b*10 + c  2^5hash = (hash << 5) - hash + c;     }System.out.println(hash);
}
  • 经验表明如果每次乘的是较大质数,可以有更好地降低 hash 冲突,因此改【乘 10】为【乘 31】
  • 【乘 31】可以等价为【乘 32 - hash】,进一步可以转为更高效地【左移5位 - hash】

检查 hash 表的分散性

public void print() {int[] sum = new int[table.length];for (int i = 0; i < table.length; i++) {Entry p = table[i];while (p != null) {sum[i]++;p = p.next;}}System.out.println(Arrays.toString(sum));Map<Integer, Long> result = Arrays.stream(sum).boxed().collect(Collectors.groupingBy(s -> s, Collectors.counting()));System.out.println(result);
}

测试

public static void main(String[] args) throws IOException {// 测试 Object.hashCodeHashTable table = new HashTable();for (int i = 0; i < 200000; i++) {Object obj = new Object();table.put(obj, obj);}table.print();// 测试 String.hashCodetable = new HashTable();List<String> strings = Files.readAllLines(Path.of("words"));for (String string : strings) {table.put(string, string);}table.print();
}

MurmurHash

在这里插入图片描述

思考

  1. 我们的代码里使用了尾插法,如果改成头插法呢?
  2. JDK 的 HashMap 中采用了将对象 hashCode 高低位相互异或的方式减少冲突,怎么理解
  3. 我们的 HashTable 中表格容量是 2 的 n 次方,很多优化都是基于这个前提,能否不用 2 的 n 次方作为表格容量?
  4. JDK 的 HashMap 在链表长度过长会转换成红黑树,对此你怎么看

习题

E01. 两数之和-Leetcode 1
public class E01Leetcode1 {public int[] twoSum(int[] nums, int target) {HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < nums.length; i++) {int k = target - nums[i];if (map.containsKey(k)) {return new int[]{i, map.get(k)};}map.put(nums[i], i);}return null; // 不会执行}
}
  • 注意:题目明确说明只会存在一个有效答案,因此不会执行到最后的 return null
E02. 无重复字符的最长字串-Leetcode 3
public int lengthOfLongestSubstring(String s) {HashMap<Character, Integer> map = new HashMap<>();int begin = 0;int maxLength = 0;for (int end = 0; end < s.length(); end++) {char ch = s.charAt(end);if (map.containsKey(ch)) { // 重复时调整 beginbegin = Math.max(begin, map.get(ch) + 1);map.put(ch, end);} else { // 不重复map.put(ch, end);}System.out.println(s.substring(begin, end + 1));maxLength = Math.max(maxLength, end - begin + 1);}return maxLength;
}

begin 调整时的解释,遇到重复的 begin 应该向右调整,例如

abca
  • 遇到重复的 a,这时 begin 应该调整到上个重复字符 a 索引加 1 处,即 map.get(‘a’) + 1 = 1,

但还有一种情况需要考虑,就是连续遇到两次重复,例如

abba
  • 遇到重复的 b,这时 begin 应该调整到上个重复字符 b 索引加 1 处,即 map.get(‘b’) + 1 = 2
  • 不过接下来,又遇到了重复的 a,此时若还执行 map.get(‘a’) + 1 = 1,则 begin 相当于向左退了,不对
  • 应该是 Math.max(2, map.get(‘a’) + 1),即 begin 应该是两个重复字符索引中更靠右者

题目中说明 s 由英文字母、数字、符号和空格组成,因此它的范围是有限的(在 0 ~127 之内),可以用数组来替代 HashMap 优化,如下

public int lengthOfLongestSubstring(String s) {int[] map = new int[128];Arrays.fill(map, -1);int begin = 0;int maxLength = 0;for (int end = 0; end < s.length(); end++) {char ch = s.charAt(end);if (map[ch] != -1) { // 重复时调整 beginbegin = Math.max(begin, map[ch] + 1);map[ch] = end;} else { // 不重复map[ch] = end;}System.out.println(s.substring(begin, end + 1));maxLength = Math.max(maxLength, end - begin + 1);}return maxLength;
}
E03. 字母异位词分组-Leetcode 49

解法1

public List<List<String>> groupAnagrams(String[] strs) {HashMap<String, List<String>> map = new HashMap<>();for (String str : strs) {char[] chars = str.toCharArray();Arrays.sort(chars);String key = new String(chars);List<String> strings = map.computeIfAbsent(key, k -> new ArrayList<>());strings.add(str);}return new ArrayList<>(map.values());
}

解法2

static class ArrayKey {int[] key = new int[26];public ArrayKey(String str) {for (int i = 0; i < str.length(); i++) {char ch = str.charAt(i);key[ch - 'a']++;}}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;ArrayKey arrayKey = (ArrayKey) o;return Arrays.equals(key, arrayKey.key);}@Overridepublic int hashCode() {return Arrays.hashCode(key);}
}public List<List<String>> groupAnagrams(String[] strs) {HashMap<ArrayKey, List<String>> map = new HashMap<>();for (String str : strs) {List<String> strings = map.computeIfAbsent(new ArrayKey(str), k -> new ArrayList<>());strings.add(str);}return new ArrayList<>(map.values());
}
E04. 判断有没有重复元素-Leetcode 217
public boolean containsDuplicate(int[] nums) { // 5msHashSet<Integer> set = new HashSet<>();for (int key : nums) {if (!set.add(key)) {return true;}}return false;
}
E05. 找出出现一次的数字-Leetcode 136

解法1:用 HashSet

public int singleNumber(int[] nums) {HashSet<Integer> set = new HashSet<>();for (int num : nums) {if (!set.add(num)) {set.remove(num);}}return set.toArray(new Integer[0])[0];
}

解法2:用 xor

public int singleNumber(int[] nums) {int num = nums[0];for (int i = 1; i < nums.length; i++) {num = num ^ nums[i];}return num;
}
E06. 判断字母异位词-Leetcode 242
public boolean isAnagram(String s, String t) { // 1msreturn Arrays.equals(getKey(s), getKey(t));
}private static int[] getKey(String s) {int[] array = new int[26];char[] chars = s.toCharArray();for (char ch : chars) {array[ch - 97]++;}return array;
}
  • 其中用 s.toCharArray() 性能明显高于用 s.charAt() 一个个获取字符
E07. 第一个不重复字符-Leetcode 387
public int firstUniqChar(String s) {int[] array = new int[26];char[] chars = s.toCharArray();for (char ch : chars) {array[ch-97]++;}for (int i = 0; i < chars.length; i++) {char ch = chars[i];if (array[ch - 97] == 1) {return i;}}return -1;
}
E08. 出现次数最多的单词-Leetcode 819

简洁解法 14 ms

public String mostCommonWord(String paragraph, String[] banned) {Set<String> banSet = Set.of(banned);HashMap<String, Integer> map = new HashMap<>();String[] split = paragraph.toLowerCase().split("[^A-Za-z]+");for (String key : split) {if(banSet.contains(key)) {continue;}map.compute(key, (k, v) -> v == null ? 1 : v + 1);}Optional<Map.Entry<String, Integer>> optional = map.entrySet().stream().max(Map.Entry.comparingByValue());return optional.map(Map.Entry::getKey).orElse(null);
}

后两行避免 lambda,12 ms

public String mostCommonWord(String paragraph, String[] banned) {Set<String> banSet = Set.of(banned);String[] split = paragraph.toLowerCase().split("[^A-Za-z]+");HashMap<String, Integer> map = new HashMap<>();for (String key : split) {if(banSet.contains(key)) {continue;}map.compute(key, (k, v) -> v == null ? 1 : v + 1);}Integer max = 0;String maxKey = null;for (Map.Entry<String, Integer> e : map.entrySet()) {Integer value = e.getValue();if (value > max) {max = value;maxKey = e.getKey();}}return maxKey;
}

避免正则匹配 5ms

public String mostCommonWord(String paragraph, String[] banned) {Set<String> banSet = Set.of(banned);HashMap<String, Integer> map = new HashMap<>();char[] chars = paragraph.toLowerCase().toCharArray();StringBuilder sb = new StringBuilder();for (char ch : chars) {if (ch >= 'a' && ch <= 'z') {sb.append(ch);} else {put(banSet, map, sb);sb = new StringBuilder();}}put(banSet, map, sb);Integer max = 0;String maxKey = null;for (Map.Entry<String, Integer> e : map.entrySet()) {Integer value = e.getValue();if (value > max) {max = value;maxKey = e.getKey();}}return maxKey;
}private static void put(Set<String> banSet, HashMap<String, Integer> map, StringBuilder sb) {if (sb.length() > 0) {String key = sb.toString();if(!banSet.contains(key)) {map.compute(key, (k, v) -> v == null ? 1 : v + 1);}}
}

sb 避免每次新建 4ms

sb.setLength(0);
E09. 根据前序与中序遍历结果构造二叉树-Leetcode105 Improved
public class E09Leetcode105Improved {//  用 hashmap 改善查找性能,其中 key 是 inOrder 值, value 是 inOrder 索引HashMap<Integer, Integer> map = new HashMap<>();public TreeNode buildTree(int[] preOrder, int[] inOrder) {for (int i = 0; i < inOrder.length; i++) {map.put(inOrder[i], i);}return helper(preOrder, 0, 0, inOrder.length - 1);}// preBegin 决定了每次在 preOrder 中找到根元素// inBegin 和 inEnd 可以用来获取区间内元素个数,结束递归等private TreeNode helper(int[] preOrder, int preBegin, int inBegin, int inEnd) {if (inBegin > inEnd) {return null;}int rootValue = preOrder[preBegin];TreeNode root = new TreeNode(rootValue);int i = map.get(rootValue);int leftSize = i - inBegin;System.out.println("元素:" + rootValue + " left[" + (preBegin + 1) + "] inOrder 索引范围[" + inBegin + "~" + (i - 1) + "]");System.out.println("元素:" + rootValue + " right[" + (preBegin + 1 + leftSize) + "] inOrder 索引范围[" + (i + 1) + "~" + inEnd + "]");root.left = helper(preOrder, preBegin + 1, inBegin, i - 1);root.right = helper(preOrder, preBegin + 1 + leftSize, i + 1, inEnd);return root;}public static void main(String[] args) {int[] preOrder = {1, 2, 4, 3, 6, 7};int[] inOrder = {4, 2, 1, 6, 3, 7};/*例如:根据根节点[1] 到中序遍历数组中一分为2,首次递归[1] 2  4  3  6  7  前0   1  2  3  4  5  前索引4  2  [1] 6  3  7  中0  1  2   3  4  5  中索引确定 preOrder 中 left 和 right 的递归起始索引,当然也要确定 inOrder 对应的两个索引位置left    right1   [2]  4  [3]  6  7  前0   1    2  3    4  5  前索引left  inOrder 索引范围: 0~1right inOrder 索引范围: 3~5*/TreeNode root = new E09Leetcode105Improved().buildTree(preOrder, inOrder);System.out.println(root);}}
E10. 根据中序与后序遍历结果构造二叉树-Leetcode106 Improved
public class E10Leetcode106Improved {HashMap<Integer, Integer> map = new HashMap<>();public TreeNode buildTree(int[] inOrder, int[] postOrder) {for (int i = 0; i < inOrder.length; i++) {map.put(inOrder[i], i);}return helper(postOrder, postOrder.length - 1, 0, inOrder.length - 1);}/*inOrder = {4,2,1,6,3,7}postOrder = {4,2,6,7,3,1}*/private TreeNode helper(int[] postOrder, int postEnd, int inBegin, int inEnd) {if (inBegin > inEnd) {return null;}int rootValue = postOrder[postEnd];TreeNode root = new TreeNode(rootValue);Integer i = map.get(rootValue);
//        int leftSize = i - inBegin;int rightSize = inEnd - i;System.out.println("元素:" + rootValue + " left[" + (postEnd - 1 - rightSize) + "] inOrder 索引范围[" + inBegin + "~" + (i - 1) + "]");System.out.println("元素:" + rootValue + " right[" + (postEnd - 1) + "] inOrder 索引范围[" + (i + 1) + "~" + inEnd + "]");root.left = helper(postOrder, postEnd - 1 - rightSize, inBegin, i - 1);root.right = helper(postOrder, postEnd - 1, i + 1, inEnd);return root;}public static void main(String[] args) {int[] postOrder = {4, 2, 6, 7, 3, 1};int[] inOrder = {4, 2, 1, 6, 3, 7};TreeNode root = new E10Leetcode106Improved().buildTree(inOrder, postOrder);System.out.println(root);}
}

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

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

相关文章

前端工程化面试题 | 16.精选前端工程化高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

vue : 无法加载文件 C:\Program Files\nodejs\node_global\vue.ps1,因为在此系统上禁止运行脚本。

解决方法&#xff1a; 打开PowerShell&#xff0c;在命令框输入set-ExecutionPolicy RemoteSigned 在PowerShell中输入会出现如下图&#xff0c;输入y即可。

数据结构-列表LinkedList

一,链表的简单的认识. 数组,栈,队列是线性数据结构,但都算不上是动态数据结构,底层都是依托静态数组,但是链表是确实真正意义上的动态数组. 为什么要学习链表? 1,链表时最简单的动态数据结构 2,掌握链表有助于学习更复杂的数据结构,例如,二叉树,trie. 3,学习链表有助于更深入…

unity学习(40)——创建(create)角色脚本(panel)——UI

1.点击不同的头像按钮&#xff0c;分别选择职业1和职业2&#xff0c;create脚本中对应的函数。 2.调取inputfield中所输入的角色名&#xff08;限制用户名长度为7字符&#xff09;&#xff0c;但愿逆向的服务器可以查重名&#xff1a; 3.点击头衔&#xff0c;显示选择的职业&a…

Spring Boot 手写starter!!!

原因&#xff1a;为什么要手写starter&#xff1f;&#xff1f;&#xff1f; 原因&#xff1a;简化功能。 实例&#xff1a;以分页为例&#xff1a;写一个starter。 1.首先定义一个PageX注解。 Target({ElementType.METHOD}) Retention(RetentionPolicy.RUNTIME) Documented p…

LeetCode 热题 100 | 二叉树(一)

目录 1 基础知识 1.1 先序遍历 1.2 中序遍历 1.3 后序遍历 2 94. 二叉树的中序遍历 3 104. 二叉树的最大深度 4 226. 翻转二叉树 5 101. 对称二叉树 菜鸟做题&#xff0c;语言是 C 1 基础知识 二叉树常见的遍历方式有&#xff1a; 先序遍历中序遍历后序遍历…

RocketMQ-架构与设计

RocketMQ架构与设计 一、简介二、框架概述1.设计特点 三、架构图1.Producer2.Consumer3.NameServer4.BrokerServer 四、基本特性1.消息顺序性1.1 全局顺序1.2 分区顺序 2.消息回溯3.消息重投4.消息重试5.延迟队列&#xff08;定时消息&#xff09;6.重试队列7.死信队列8.消息语…

神经网络系列---感知机(Neuron)

文章目录 感知机(Neuron)感知机(Neuron)的决策函数可以表示为&#xff1a;感知机(Neuron)的学习算法主要包括以下步骤&#xff1a;感知机可以实现逻辑运算中的AND、OR、NOT和异或(XOR)运算。 感知机(Neuron) 感知机(Neuron)是一种简单而有效的二分类算法&#xff0c;用于将输入…

jmeter下载base64加密版pdf文件

一、何为base64加密版pdf文件 如下图所示&#xff0c;接口jmeter执行后&#xff0c;返回一串包含大小写英文字母、数字、、/、的长字符串&#xff0c;直接另存为pdf文件后&#xff0c;文件有大小&#xff0c;但是打不开&#xff1b;另存为doc文件后&#xff0c;打开可以看到和…

Puppeteer 使用实战:如何将自己的 CSDN 专栏文章导出并用于 Hexo 博客(二)

文章目录 上一篇效果演示Puppeteer 修改浏览器的默认下载位置控制并发数错误重试并发控制 错误重试源码 上一篇 Puppeteer 使用实战&#xff1a;如何将自己的 CSDN 专栏文章导出并用于 Hexo 博客&#xff08;一&#xff09; 效果演示 上一篇实现了一些基本功能&#xff0c;…

Maxwell安装部署

1 Maxwell输出格式 database&#xff1a;变更数据所属的数据库table&#xff1a;变更数据所属的表type&#xff1a;数据变更类型ts&#xff1a;数据变更发生的时间xid&#xff1a;事务idcommit&#xff1a;事务提交标志&#xff0c;可用于重新组装事务data&#xff1a;对于inse…

uni-app nvue vue3 setup中实现加载webview,解决nvue中获取不到webview实例的问题

注意下面的方法只能在app端使用&#xff0c; let wv plus.webview.create("","custom-webview",{plusrequire:"none", uni-app: none, width: 300,height:400,top:uni.getSystemInfoSync().statusBarHeight44 }) wv.loadURL("https://ww…

浅析Linux设备驱动:DMA内存映射

文章目录 概述DMA与Cache一致性DMA映射类型一致性DMA映射dma_alloc_coherent 流式DMA映射dma_map_single数据同步操作dma_direct_sync_single_for_cpudma_direct_sync_single_for_device 相关参考 概述 现代计算机系统中&#xff0c;CPU访问内存需要经过Cache&#xff0c;但外…

第6.4章:StarRocks查询加速——Colocation Join

目录 一、StarRocks数据划分 1.1 分区 1.2 分桶 二、Colocation Join实现原理 2.1 Colocate Join概述 2.2 Colocate Join实现原理 三、应用案例 注&#xff1a;本篇文章阐述的是StarRocks-3.2版本的Colocation Join 官网文章地址&#xff1a; Colocate Join | StarRoc…

32单片机基础:GPIO输出

目录 简介&#xff1a; GPIO输出的八种模式 STM32的GPIO工作方式 GPIO支持4种输入模式&#xff1a; GPIO支持4种输出模式&#xff1a; 浮空输入模式 上拉输入模式 下拉输入模式 模拟输入模式&#xff1a; 开漏输出模式&#xff1a;&#xff08;PMOS无效&#xff0c;就…

【笔记】【开发方案】APN 配置参数 bitmask 数据转换(Android KaiOS)

一、参数说明 &#xff08;一&#xff09;APN配置结构对比 平台AndroidKaiOS文件类型xmljson结构每个<apn>标签是一条APN&#xff0c;包含完成的信息层级数组结构&#xff0c;使用JSON格式的数据。最外层是mcc&#xff0c;其次mnc&#xff0c;最后APN用数组形式配置&am…

(done) 什么是正定矩阵?Positive Definite Matrices

正定矩阵的定义&#xff1a;https://baike.baidu.com/item/%E6%AD%A3%E5%AE%9A%E7%9F%A9%E9%98%B5/11030459 正定矩阵的作用、验证视频&#xff1a;https://www.bilibili.com/video/BV1Ag411M76G/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c…

UE4 C++联网RPC教程笔记(三)(第8~9集)完结

UE4 C联网RPC教程笔记&#xff08;三&#xff09;&#xff08;第8~9集&#xff09;完结 8. exe 后缀实现监听服务器9. C 实现监听服务器 8. exe 后缀实现监听服务器 前面我们通过蓝图节点实现了局域网连接的功能&#xff0c;实际上我们还可以给项目打包后生成的 .exe 文件创建…

【力扣hot100】刷题笔记Day10

前言 一鼓作气把链表给刷完&#xff01;&#xff01;中等题困难题冲冲冲啊啊啊&#xff01; 25. K 个一组翻转链表 - 力扣&#xff08;LeetCode&#xff09; 模拟 class Solution:def reverseKGroup(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:# 翻转…

C语言中的字体背景颜色汇总

客官请看效果 客官请看代码 #include <stdio.h> #include <stdlib.h> #include <windows.h>int main() {int i;for (i 0; i < 254; i) {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), i); // 设置当前文本颜色为循环变量对应的颜色printf(…