算法解析-经典150(矩阵、哈希表)

news2025/1/6 12:44:48

文章目录

  • 矩阵
    • 1.有效的数独
        • 1.答案
        • 2.思路
    • 2.螺旋矩阵
        • 1.答案
        • 2.思路
    • 3.旋转图像
        • 1.答案
        • 2.思路
    • 4.矩阵置零
        • 1.答案
        • 2.思路
  • 哈希表
    • 1.赎金信
        • 1.答案
        • 2.思路
    • 2.同构字符串
        • 1.答案
        • 2.思路
    • 3.单词规律
        • 1.答案
        • 2.思路
    • 4.有效的字母异位词
        • 1.答案
        • 2.思路
    • 5.字母异位词分组
        • 1.答案
        • 2.思路
    • 6.两数之和
        • 1.答案
        • 2.思路
    • 7.快乐数
        • 1.答案
        • 2.思路
    • 8.存在重复元素 II
        • 1.答案
        • 2.思路
    • 9.最长连续序列
        • 1.答案
        • 2.思路

矩阵

1.有效的数独

1.答案
package com.sunxiansheng.classic150.g1;

/**
 * Description: 36. 有效的数独
 *
 * @Author sun
 * @Create 2024/12/22 10:02
 * @Version 1.0
 */
public class t36 {

    public boolean isValidSudoku(char[][] board) {
        boolean[][] rows = new boolean[9][9];
        boolean[][] cols = new boolean[9][9];
        boolean[][] boxes = new boolean[9][9];
        int m = board.length;
        int n = board[0].length;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                // 获取元素
                char c = board[i][j];
                // 跳过空格
                if (c == '.') {
                    continue;
                }
                // 转换为索引,方便存入数组
                int index = c - '1';
                // 放入当前行
                if (rows[i][index]) {
                    return false;
                } else {
                    rows[i][index] = true;
                }
                // 放入当前列
                if (cols[index][j]) {
                    return false;
                } else {
                    cols[index][j] = true;
                }
                // 计算3x3子宫格的索引
                int boxIndex = (i / 3) * 3 + j / 3;
                if (boxes[boxIndex][index]) {
                    return false;
                } else {
                    boxes[boxIndex][index] = true;
                }
            }
        }
        return true;
    }
}
2.思路

记住这个公式:int boxIndex = (i / 3) * 3 + j / 3;

2.螺旋矩阵

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.ArrayList;
import java.util.List;

/**
 * Description: 54. 螺旋矩阵
 *
 * @Author sun
 * @Create 2024/12/22 10:43
 * @Version 1.0
 */
public class t54 {

    public static List<Integer> spiralOrder(int[][] matrix) {
        List<Integer> res = new ArrayList<>();
        int m = matrix.length;
        int n = matrix[0].length;
        // 定义上下左右边界
        int top = 0;
        int bottom = m - 1;
        int left = 0;
        int right = n - 1;
        // 计算一共需要遍历的次数
        int total = m * n;
        int count = 0;
        // 按照右下左上的顺序遍历
        while (true) {
            // 右
            for (int i = left; i <= right; i++) {
                res.add(matrix[top][i]);
                if (++count == total) {
                    return res;
                }
            }
            // 上边界下移
            top++;
            // 下
            for (int i = top; i <= bottom; i++) {
                res.add(matrix[i][right]);
                if (++count == total) {
                    return res;
                }
            }
            // 右边界左移
            right--;
            // 左
            for (int i = right; i >= left; i--){
                res.add(matrix[bottom][i]);
                if (++count == total) {
                    return res;
                }
            }
            // 下边界上移
            bottom--;
            // 上
            for (int i = bottom; i >= top; i--) {
                res.add(matrix[i][left]);
                if (++count == total) {
                    return res;
                }
            }
            // 左边界右移
            left++;
        }
    }
}
2.思路

先定义四个边界,然后记录一共需要遍历的次数,最后在循环内按照顺序遍历,每次遍历完成都要移动边界

3.旋转图像

1.答案
package com.sunxiansheng.classic150.g1;

/**
 * Description: 48. 旋转图像
 *
 * @Author sun
 * @Create 2024/12/22 11:11
 * @Version 1.0
 */
public class t48 {

    public static void rotate(int[][] matrix) {
        // 矩阵转置
        int n = matrix.length;
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
        // 将每一行都逆序
        for (int i = 0; i < matrix.length; i++) {
            reverse(matrix[i]);
        }
    }

    /**
     * 逆序数组
     *
     * @param arr
     */
    private static void reverse(int[] arr) {
        int left = 0;
        int right = arr.length - 1;
        while (left < right) {
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}
2.思路

转置后逆序即可

4.矩阵置零

1.答案
package com.sunxiansheng.classic150.g1;

import javafx.util.Pair;

import java.util.ArrayList;
import java.util.List;

/**
 * Description: 73. 矩阵置零
 *
 * @Author sun
 * @Create 2024/12/22 11:20
 * @Version 1.0
 */
public class t73 {

    public static void setZeroes(int[][] matrix) {
        // 记录一下需要置0的下标
        List<Pair<Integer, Integer>> list = new ArrayList<>();
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[0].length; j++) {
                if (matrix[i][j] == 0) {
                    list.add(new Pair<>(i, j));
                }
            }
        }
        // 设置0
        for (int i = 0; i < list.size(); i++) {
            setZero(matrix, list.get(i).getKey(), list.get(i).getValue());
        }
    }

    private static void setZero(int[][] matrix, int row, int col) {
        int top = 0;
        int bottom = matrix.length - 1;
        int left = 0;
        int right = matrix[0].length - 1;
        // 向上置0
        for (int i = row; i >= top; i--) {
            matrix[i][col] = 0;
        }
        // 向下
        for (int i = row; i <= bottom; i++) {
            matrix[i][col] = 0;
        }
        // 向左
        for (int i = left; i <= col; i++) {
            matrix[row][i] = 0;
        }
        // 向右
        for (int i = right; i >= col; i--) {
            matrix[row][i] = 0;
        }
    }
}
2.思路

先要记录一下要置0的下标,然后遍历去置0即可

哈希表

1.赎金信

1.答案
package com.sunxiansheng.classic150.g1;

/**
 * Description: 383. 赎金信
 *
 * @Author sun
 * @Create 2024/12/22 13:27
 * @Version 1.0
 */
public class t383 {

    public static boolean canConstruct(String ransomNote, String magazine) {
        // 统计字符频率
        int[] mFreq = new int[26];
        for (int i = 0; i < magazine.length(); i++) {
            mFreq[magazine.charAt(i) - 'a'] ++;
        }
        // 遍历ransomNote看看够不够减
        for (int i = 0; i < ransomNote.length(); i++) {
            // 计算下标
            int index = ransomNote.charAt(i) - 'a';
            if (--mFreq[index] < 0) {
                return false;
            }
        }
        return true;
    }
}
2.思路

先统计一下字符的频率,然后看看够不够减就可以

2.同构字符串

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.HashMap;
import java.util.Map;

/**
 * Description: 205. 同构字符串
 *
 * @Author sun
 * @Create 2024/12/22 13:44
 * @Version 1.0
 */
public class t205 {

    public boolean isIsomorphic(String s, String t) {
        if (s.length() != t.length()) {
            return false;
        }
        // 双向映射:s -> t 和 t -> s
        Map<Character, Character> mapS2T = new HashMap<>();
        Map<Character, Character> mapT2S = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            // 获取元素
            char charS = s.charAt(i);
            char charT = t.charAt(i);
            // 检查s到t是否有映射
            if (mapS2T.containsKey(charS)) {
                // 有映射就检查当前映射
                if (mapS2T.get(charS) != charT) {
                    return false;
                }
            } else {
                // 没有映射就建立映射
                mapS2T.put(charS, charT);
            }
            // 检查t到s是否有映射
            if (mapT2S.containsKey(charT)) {
                // 有映射就检查当前映射
                if (mapT2S.get(charT) != charS) {
                    return false;
                }
            } else {
                // 没有映射就建立映射
                mapT2S.put(charT, charS);
            }
        }
        return true;
    }
}
2.思路

就是检查双向映射,具体检查的过程就是:先判断有没有映射,如果有则检查,没有就建立映射

3.单词规律

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * Description: 290. 单词规律
 *
 * @Author sun
 * @Create 2024/12/22 14:06
 * @Version 1.0
 */
public class t290 {

    public static boolean wordPattern(String pattern, String s) {
        // s以空格分割
        String[] split = s.split(" ");
        if (split.length != pattern.length()) {
            return false;
        }
        // 双向映射
        Map<Character, String> map = new HashMap<>();
        Map<String, Character> map2 = new HashMap<>();
        for (int i = 0; i < pattern.length(); i++) {
            // 取数
            char left = pattern.charAt(i);
            String right = split[i];
            // 检查是否有映射
            if (map.containsKey(left)) {
                // 如果有,则检查映射
                if (!map.get(left).equals(right)) {
                    return false;
                }
            } else {
                // 如果没有,就添加映射
                map.put(left, right);
            }

            // 检查是否有映射
            if (map2.containsKey(right)) {
                // 如果有,则检查映射
                if (!map2.get(right).equals(left)) {
                    return false;
                }
            } else {
                // 如果没有,就添加映射
                map2.put(right, left);
            }

        }
        return true;
    }
}
2.思路

也是一个双向映射

4.有效的字母异位词

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.Arrays;

/**
 * Description: 242. 有效的字母异位词
 *
 * @Author sun
 * @Create 2024/12/22 14:22
 * @Version 1.0
 */
public class t242 {

    public static boolean isAnagram(String s, String t) {
        // 计算频率,看频率是否相同
        int[] sFeq = new int[26];
        int[] tFeq = new int[26];

        for (int i = 0; i < s.length(); i++) {
            sFeq[s.charAt(i) - 'a']++;
        }
        for (int j = 0; j < t.length(); j++) {
            tFeq[t.charAt(j) - 'a']++;
        }

        return Arrays.equals(sFeq, tFeq);
    }
}
2.思路

就是转化为频率数组,判断两个数组是不是一样就可以

5.字母异位词分组

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.*;

/**
 * Description: 49. 字母异位词分组
 *
 * @Author sun
 * @Create 2024/12/22 14:29
 * @Version 1.0
 */
public class t49 {

    public static List<List<String>> groupAnagrams(String[] strs) {
        List<List<String>> res = new ArrayList<>();
        if (strs == null || strs.length == 0) {
            return res;
        }
        // 存储结果的map
        Map<String, List<String>> map = new HashMap<>();
        for (int i = 0; i < strs.length; i++) {
            char[] charArray = strs[i].toCharArray();
            // 排序
            Arrays.sort(charArray);
            // 转换为String
            String key = String.valueOf(charArray);
            // 判断map中是否有相同的
            List<String> list = null;
            if (map.containsKey(key)) {
                list = map.get(key);
            } else {
                list = new ArrayList<>();
            }
            list.add(strs[i]);
            map.put(key, list);
        }
        return new ArrayList<>(map.values());
    }
}
2.思路

就是使用一个map,其中的key是排序后的字符串,value就是与排序后的字符串相同的元素,遍历去比较即可

6.两数之和

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.HashMap;
import java.util.Map;

/**
 * Description: 1. 两数之和
 *
 * @Author sun
 * @Create 2024/12/22 14:52
 * @Version 1.0
 */
public class t1 {

    public static int[] twoSum(int[] nums, int target) {
        // 哈希表来记录
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            // 计算差
            int diff = target - nums[i];
            // 如果map中有这个差值对应的就返回结果
            if (map.containsKey(diff)) {
                return new int[]{i, map.get(diff)};
            }
            // 如果没有,就把自己放到map中
            map.put(nums[i], i);
        }
        return null;
    }
}
2.思路

就是使用哈希表来记录元素以及元素下标,然后遍历的时候先判断哈希表中有没有目标元素减去当前元素的差,如果有就直接返回,没有就将当前元素放到map中

7.快乐数

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.HashSet;
import java.util.Set;

/**
 * Description: 202. 快乐数
 *
 * @Author sun
 * @Create 2024/12/22 15:20
 * @Version 1.0
 */
public class t202 {

    public static boolean isHappy(int n) {
        // 使用集合来记录结果,也可以判断是否重复
        Set<Integer> set = new HashSet<>();
        while (n != 1) {
            int num = getNum(n);
            // 只要set中出现了num那么就是重复了直接返回false
            if (set.contains(num)) {
                return false;
            }
            set.add(num);
            n = num;
        }
        return true;
    }

    /**
     * 获取这个数每个位置的平方和
     *
     * @return
     */
    private static int getNum(int num) {
        int res = 0;
        while (num > 0) {
            int cur = num % 10;
            res += cur * cur;
            num /= 10;
        }
        return res;
    }

    public static void main(String[] args) {
        isHappy(19);
    }
}
2.思路

使用set来记录计算后的结果,核心就是在加入之前先判断set中是否已经有这个结果了,如果有,就是开始重复了,表明不是快乐数

8.存在重复元素 II

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.HashMap;
import java.util.Map;

/**
 * Description: 219. 存在重复元素 II
 *
 * @Author sun
 * @Create 2024/12/22 15:36
 * @Version 1.0
 */
public class t219 {

    public static boolean containsNearbyDuplicate(int[] nums, int k) {
        // map存储
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            // 如果map中有
            if (map.containsKey(nums[i])) {
                // 进一步判断是否满足要求
                if (Math.abs(map.get(nums[i]) - i) <= k) {
                    // 如果满足要求就直接返回
                    return true;
                }
                // 不满足要求就更新map
                map.put(nums[i], i);
            } else {
                // 没有就添加到map中
                map.put(nums[i], i);
            }
        }
        return false;
    }

    public static void main(String[] args) {
        System.out.println("containsNearbyDuplicate(new int[]{1,0,1,1}, 1) = " + containsNearbyDuplicate(new int[]{1, 0, 1, 1}, 1));
    }
}
2.思路

使用map来存储元素和下标,先判断map中有没有与当前元素相同的元素,如果没有就加入到map,如果有,就进一步判断是否能满足要求,如果满足就返回结果,如果不满足就更新map

9.最长连续序列

1.答案
package com.sunxiansheng.classic150.g1;

import java.util.Arrays;

/**
 * Description: 128. 最长连续序列
 *
 * @Author sun
 * @Create 2024/12/23 12:52
 * @Version 1.0
 */
public class t128 {

    public static int longestConsecutive(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int res = 1;
        // 1 2 3 3 4 100 200
        Arrays.sort(nums);
        // dp[i]:以i结尾的最长连续序列的长度
        // 状态转移:当nums[i] == nums[i - 1] + 1 dp[i] = dp[i - 1] + 1
        // 当nums[i] == nums[i - 1] dp[i] = dp[i - 1]
        // 当nums[i] > nums[i - 1] + 1 dp[i] = 1
        // 初始化
        int[] dp = new int[nums.length];
        dp[0] = 1;
        for (int i = 1; i < dp.length; i++) {
            dp[i] = 1;
            if (nums[i] == nums[i - 1] + 1) {
                dp[i] = dp[i - 1] + 1;
            } else if (nums[i] == nums[i - 1]) {
                dp[i] = dp[i - 1];
            } else {
                dp[i] = 1;
            }
            res = Math.max(res, dp[i]);
        }
        return res;
    }

    public static void main(String[] args) {
        System.out.println("longestConsecutive(new int[]{1,2,3,3,4,100,200}) = " + longestConsecutive(new int[]{1, 2, 3, 3, 4, 100, 200}));
    }
}
2.思路

首先对数组排序,然后使用动态规划,定义为dp[i]:以i结尾的最长连续序列的长度,分为三种情况,第一种是当前元素等于前一个元素加一,那么dp[i] = dp[i - 1] + 1,第二种是当前元素跟前一个元素相同,dp[i] = dp[i - 1] 最后一种情况就是当前元素比前一个元素加一还要大,就说明不是连续的,所以当前元素结尾的最长连续序列的长度就是1

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

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

相关文章

数据结构与算法Python版 图的应用与广度优先搜索

文章目录 一、图的应用-词梯问题二、图的广度优先搜索 一、图的应用-词梯问题 词梯问题 Word Ladder 从一个单词演变到另一个单词&#xff0c;其中的过程可以经过多个中间单词。要求是相邻两个单词之间差异只能是1个字母如FOOL变SAGE&#xff1a;FOOL >> POOL >>…

服务器数据恢复—服务器硬盘亮黄灯的数据恢复案例

服务器硬盘指示灯闪烁黄灯是一种警示&#xff0c;意味着服务器硬盘出现故障即将下线。发现这种情况建议及时更换硬盘。 一旦服务器上有大量数据频繁读写&#xff0c;硬盘指示灯会快速闪烁。服务器上某个硬盘的指示灯只有黄灯亮着&#xff0c;而其他颜色的灯没有亮的话&#xff…

Java SpringBoot使用EasyExcel导入导出Excel文件

点击下载《Java SpringBoot使用EasyExcel导入导出Excel文件(源代码)》 在 Java Spring Boot 项目中&#xff0c;导入&#xff08;读取&#xff09;和导出&#xff08;写入&#xff09; Excel 文件是一项常见的需求。EasyExcel 是阿里巴巴开源的一个用于简化 Java 环境下 Excel…

Deduction(演绎法)和Reduction(还原法)-关于中西方思维的差异

Deduction(演绎法)和Reduction(还原法)-关于中西方思维的差异 最近看到中国新一代战机上天的消息,感慨万千;忽然想起来两年多前一次爬山的时候,一个友人跟我大概说过,Deduction和Reduction分别对应了中国古代和西方古代以来的思考自然和技术发明的思想.于是又在这方面琢磨了一番…

unity学习6:unity的3D项目的基本操作

目录 1 unity界面的基本认识 1.1 file 文件 1.2 edit 编辑/操作 1.3 Assets 1.4 gameobject 游戏对象 1.5 组件 1.6 windows 2 这些部分之间的关系 2.1 关联1&#xff1a; Assets & Project 2.2 关联2&#xff1a;gameobject & component 2.3 关联3&#xff…

【银河麒麟高级服务器操作系统实例】tcp半链接数溢出分析及处理全过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://document.kylinos.cn 服务器环境以及配置 系统环境 物理机/虚拟机/云…

k8s基础(2)—Kubernetes-Namespace

一、Namespace概述 名字空间 在 Kubernetes 中&#xff0c;名字空间&#xff08;Namespace&#xff09; 提供一种机制&#xff0c;将同一集群中的资源划分为相互隔离的组。 同一名字空间内的资源名称要唯一&#xff0c;但跨名字空间时没有这个要求。 名字空间作用域仅针对带有…

.NET框架用C#实现PDF转HTML

HTML作为一种开放标准的网页标记语言&#xff0c;具有跨平台、易于浏览和搜索引擎友好的特性&#xff0c;使得内容能够在多种设备上轻松访问并优化了在线分享与互动。通过将PDF文件转换为HTML格式&#xff0c;我们可以更方便地在浏览器中展示PDF文档内容&#xff0c;同时也更容…

医学图像分析工具01:FreeSurfer || Recon -all 全流程MRI皮质表面重建

FreeSurfer是什么 FreeSurfer 是一个功能强大的神经影像学分析软件包&#xff0c;广泛用于处理和可视化大脑的横断面和纵向研究数据。该软件由马萨诸塞州总医院的Martinos生物医学成像中心的计算神经影像实验室开发&#xff0c;旨在为神经科学研究人员提供一个高效、精确的数据…

JavaScript 基础2

js的运算符 算数运算符 相加求和&#xff0c;如果用在字符串则是拼接 -相减求差 *相乘求积 /相除求商 %模除求余 具体用法如下 let num 154 let num2 15 document.write(numnum2) document.write(<br>) document.write(num-num2) document.write(<br>) do…

Leecode刷题C语言之我的日程安排表②

执行结果:通过 执行用时和内存消耗如下&#xff1a; typedef struct {int start;int end; }BOOKING;#define MAX_BOOK_NUM (1000) typedef struct MyCalendar_ {BOOKING book[MAX_BOOK_NUM];int bnum;BOOKING *sorted[MAX_BOOK_NUM];int num;int conflict[MAX_BOOK_NUM];int c…

【C语言的小角落】--- 深度理解取余/取模运算

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; C语言的小角落 本篇博客我们来深度理解取余/取模&#xff0c;以及它们在不同语言中出现不同现象的原因。 &#x1f3e0; 关于取整 &#x1f3b5; 向0取整…

网关的主要类型和它们的特点

网关&#xff0c;作为网络通信的关键节点&#xff0c;根据其应用场景和功能特点&#xff0c;可以分为多种类型。 1.协议网关 特点&#xff1a; • 协议转换&#xff1a;协议网关的核心功能是转换不同网络之间的通信协议。例如&#xff0c;它可以将IPv4协议的数据包转换为IPv6协…

聆听音乐 1.5.9 | 畅听全网音乐,支持无损音质下载

聆听音乐手机版是面向广大音乐爱好者的移动应用程序&#xff0c;用户可以随时随地通过手机享受丰富的音乐资源。它提供了多种魅力功能&#xff0c;让用户在手机上畅享更舒适的音乐体验&#xff0c;每位用户都能享受精彩纷呈的收听体验。此外&#xff0c;软件还支持无损音质音乐…

实现一个通用的树形结构构建工具

文章目录 1. 前言2. 树结构3. 具体实现逻辑3.1 TreeNode3.2 TreeUtils3.3 例子 4. 小结 1. 前言 树结构的生成在项目中应该都比较常见&#xff0c;比如部门结构树的生成&#xff0c;目录结构树的生成&#xff0c;但是大家有没有想过&#xff0c;如果在一个项目中有多个树结构&…

“善弈者”也需妙手,Oclean欧可林:差异化不是说说而已

作者 | 曾响铃 文 | 响铃说 俗话说&#xff0c;“牙痛不是病&#xff0c;痛起来要人命”。这话意思大家都知道&#xff0c;牙痛虽不是什么大病&#xff0c;可一旦发作却是极难忍受。 前几日&#xff0c;Oclean欧可林举办了一场AirPump A10氧气啵啵冲牙器新品品鉴会&#xff…

汇编语言与接口技术--跑马灯

一、 实验要求 在单片机开发板的LED灯D1~D8上实现跑马灯。LED与单片机引脚连线电路如下图: 单片机芯片选择AT89C51&#xff0c;晶振频率设为12MHz&#xff0c;操作参考单片机开发板使用说明。跑马灯点亮的时间间隔约为1秒。分别用定时器的模式1和模式2实现。&#xff08;用P83…

基于数据融合的智能家居环境监测系统研究与设计(论文+源码)

1总体方案设计 本次基于数据融合的智能家居环境监测系统的设计&#xff0c;其系统总体架构如图2.1所示&#xff0c;整个系统在器件上包括了主控制器STM32F103单片机&#xff0c;MQ可燃气体传感器&#xff0c;光照传感器&#xff0c;DHT11温湿度传感器&#xff0c;风扇&#xff…

Mac中配置Node.js前端vscode环境(第二期)

核心组件&#xff1a;vscode、谷歌浏览器、Node.js&#xff08;重点&#xff09;、git 一、Node.js安装&#xff08;nvm安装&#xff09; 点击macos中的终端&#xff0c;保持bash&#xff0c;而不是zsh 若为zsh&#xff0c;则可在终端中使用下面命令变成bash chsh -s /bin/…

基于SpringBoot和Thymeleaf的仿小米电商系统源码下载与安装指南-幽络源

项目概述 这是一个基于 Spring Boot 2.X 和 Thymeleaf 技术栈的仿小米电商系统。该项目包括了前台商城系统和后台管理系统&#xff0c;经幽络源测试具备完整的电商功能&#xff0c;适合用作学习、参考或作为开发电商系统的基础。 前台商城系统&#xff1a; 包括首页登录、商品…