代码随想录-Day35

news2024/11/24 10:34:48

134. 加油站

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

示例 1:

输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释:
从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。
示例 2:

输入: gas = [2,3,4], cost = [3,4,3]
输出: -1
解释:
你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。

方法一:

// 解法1
class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int sum = 0;
        int min = 0;
        for (int i = 0; i < gas.length; i++) {
            sum += (gas[i] - cost[i]);
            min = Math.min(sum, min);
        }

        if (sum < 0) return -1;
        if (min >= 0) return 0;

        for (int i = gas.length - 1; i > 0; i--) {
            min += (gas[i] - cost[i]);
            if (min >= 0) return i;
        }

        return -1;
    }
}

这段Java代码是用于解决“环形赛道加油问题”的一种解法。给定两个长度相等的整数数组 gascost,分别表示在环形赛道上每个地点的汽油量和从该地点出发到达下一个地点所需的汽油量。该函数 canCompleteCircuit 的目的是找到一个起始加油站,使得一辆恰好能完成环形赛道一圈的行程,即车能够在途中不耗尽汽油。如果可行,返回起始加油站的编号,否则返回 -1

代码解析:

  1. 计算总差值 sum 和最小差值 min
    首先,遍历数组一次,累加 gas[i] - cost[i] 的值到 sum,同时维护这个差值序列中的最小值 min。这一步是为了判断整个环形赛道上是否有足够的汽油完成一圈。如果 sum < 0,说明总的汽油不足以覆盖总成本,直接返回 -1

  2. 判断是否有解

    • 如果 min >= 0,说明从任一位置出发都能完成环形赛道,因为最“不利”的点也能保持油量非负,故返回 0 作为起始点(实际上任一起点均可)。
    • 否则,需要找到第一个能够让累计汽油量由负转正的位置,即为起始加油站。
  3. 寻找起始加油站
    从数组末尾向前遍历到第二个元素(因为第一个元素是否符合条件已在前面判断),累加 gas[i] - cost[i]min,一旦 min 变为非负,即找到了能够作为起始加油站的位置,返回当前索引 i

  4. 无解情况
    如果遍历结束都没有找到满足条件的起始位置,则返回 -1 表示无法完成一圈行程。

注意点:

  • 该解法在第二次遍历时其实没有必要,因为第一次遍历已经能够确定是否有解以及起始位置。正确的逻辑是在第一次遍历时记录下 min 对应的索引,如果 sum >= 0 则直接返回该索引作为起始位置。如果我的描述有误,请允许我更正:根据原始代码逻辑,第二次遍历实则是冗余的,应该在第一次遍历时记录下 min 首次出现时的索引(若 sum >= 0),并在循环结束后检查是否找到了这样的起始位置。正确的逻辑应该简化并修正这部分。

方法二:

// 解法2
class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int curSum = 0;
        int totalSum = 0;
        int index = 0;
        for (int i = 0; i < gas.length; i++) {
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if (curSum < 0) {
                index = (i + 1) % gas.length ; 
                curSum = 0;
            }
        }
        if (totalSum < 0) return -1;
        return index;
    }
}

这段Java代码提供了另一种更为简洁且正确的解法来解决“环形赛道加油问题”。与之前的解法相比,这个版本在单次遍历中就完成了所有必要的计算,避免了冗余的循环。下面是这个解法的详细解析:

代码解析:

  • 变量初始化

    • curSum 初始化为0,用于记录从当前起点开始累积的汽油剩余量。
    • totalSum 初始化为0,用于记录整个环形赛道上汽油总量与成本总量之差。
    • index 初始化为0,用于记录可能的起始加油站位置。
  • 单次遍历
    遍历数组一次,对于每个位置 i

    • 更新 curSum 为当前位置的汽油减去成本,即 curSum += gas[i] - cost[i]
    • 累加到 totalSum 中,用于最后判断是否有解。
    • 如果 curSum 小于0,说明从当前起点无法继续行驶到下一个位置,此时更新 index 为下一个位置 (i + 1) % gas.length,并重置 curSum 为0,表示从这个新位置重新尝试开始计算剩余油量。
  • 判断是否有解

    • 在遍历结束后,检查 totalSum 是否小于0,如果是,则说明整个环形赛道上的汽油总量不足以覆盖行驶的总成本,返回 -1
    • 如果 totalSum >= 0,则返回之前记录的 index 作为可以成功完成一圈的起始加油站位置。注意,这里的 index 实际上记录的是“下一个”加油站的索引,因为在遍历中一旦累加的油量不足就立即更新了 index,因此最终的 index 是理论上最后一个“失败点”的下一个位置,也就是实际的起始位置。

这个解法高效地解决了问题,仅通过一次遍历就找到了可能的起始加油站或者确定了无解的情况。

135. 分发糖果

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。

你需要按照以下要求,给这些孩子分发糖果:

每个孩子至少分配到 1 个糖果。
相邻两个孩子评分更高的孩子会获得更多的糖果。
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。

示例 1:

输入:ratings = [1,0,2]
输出:5
解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例 2:

输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。
在这里插入图片描述

class Solution {
    /**
         分两个阶段
         1、起点下标1 从左往右,只要 右边 比 左边 大,右边的糖果=左边 + 1
         2、起点下标 ratings.length - 2 从右往左, 只要左边 比 右边 大,此时 左边的糖果应该 取本身的糖果数(符合比它左边大) 和 右边糖果数 + 1 二者的最大值,这样才符合 它比它左边的大,也比它右边大
    */
    public int candy(int[] ratings) {
        int len = ratings.length;
        int[] candyVec = new int[len];
        candyVec[0] = 1;
        for (int i = 1; i < len; i++) {
            candyVec[i] = (ratings[i] > ratings[i - 1]) ? candyVec[i - 1] + 1 : 1;
        }

        for (int i = len - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1]) {
                candyVec[i] = Math.max(candyVec[i], candyVec[i + 1] + 1);
            }
        }

        int ans = 0;
        for (int num : candyVec) {
            ans += num;
        }
        return ans;
    }
}

这段Java代码是用于解决“糖果分配问题”的一个经典实现。给定一个表示孩子们评分的整数数组 ratings,你需要按照以下要求给孩子们分发糖果:

  1. 每个孩子至少得到一个糖果
  2. 如果一个孩子的评分比他旁边的孩子高,那么这个孩子应该得到更多的糖果

目标是求出最少需要多少糖果。

代码解析:

  1. 初始化:首先,根据题目要求初始化一个长度与 ratings 相同的数组 candyVec 用于存储每个孩子应得的糖果数,并初始化 candyVec[0] 为1,因为至少有一个糖果。

  2. 第一阶段遍历:从左到右遍历 ratings,如果当前孩子的评分比前一个孩子高,那么他在 candyVec 中对应的糖果数就设置为前一个孩子糖果数加1,否则至少分配1个糖果。这一步确保了每个孩子比左边评分低的孩子多至少一个糖果。

  3. 第二阶段遍历:然后从右到左遍历 ratings(从倒数第二个孩子开始,因为最后一个孩子已经在第一阶段考虑过了),对于每个孩子,如果他的评分比右边的孩子高,那么他的糖果数应该更新为他自己当前的糖果数与右边孩子糖果数加1之间的较大值。这样确保了每个孩子也比右边评分低的孩子多至少一个糖果,同时考虑到两边都比较的情况,保证分配合理。

  4. 计算总数:最后,遍历 candyVec 数组,将所有孩子的糖果数相加,得到最小需要的糖果总数。

  5. 返回结果:返回糖果总数 ans

总结:

该算法通过两次遍历确保了每个孩子的糖果数满足题目的两个条件,同时尽可能地减少了糖果的总消耗,是一种既直观又高效的解决方案。

860. 柠檬水找零

在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。

每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。

注意,一开始你手头没有任何零钱。

给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。

示例 1:

输入:bills = [5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。
示例 2:

输入:bills = [5,5,10,10,20]
输出:false
解释:
前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。

class Solution {
    public boolean lemonadeChange(int[] bills) {
        int five = 0;
        int ten = 0;

        for (int i = 0; i < bills.length; i++) {
            if (bills[i] == 5) {
                five++;
            } else if (bills[i] == 10) {
                five--;
                ten++;
            } else if (bills[i] == 20) {
                if (ten > 0) {
                    ten--;
                    five--;
                } else {
                    five -= 3;
                }
            }
            if (five < 0 || ten < 0) return false;
        }
        
        return true;
    }
}

这段代码是用来解决“柠檬水找零”问题的,具体问题是这样的:你是一个卖柠檬水的小摊贩,手上最初只有足够的零钱可以找开5美元、10美元和20美元的钞票。每当顾客付给你一张钞票时,你必须提供正确数额的找零。如果能找回零钱,该函数返回true,否则返回false

代码解析:

  • 初始化两个整型变量fiveten,分别表示手头上5美元和10美元的钞票数量,初始都为0。
  • 使用for循环遍历输入数组bills,数组中的每个元素代表顾客给的钞票面额。
    • 如果顾客给的是5美元,那么5美元的钞票数量five加1。
    • 如果顾客给的是10美元,那么需要找回5美元,因此5美元的数量减1,10美元的数量加1。
    • 如果顾客给的是20美元,优先考虑如果有10美元和5美元的情况,即10美元减1张,5美元减1张;如果没有10美元,则需要3张5美元来找零,因此5美元的数量减3。
    • 在每次处理完一笔交易后,检查是否有足够的5美元和10美元(即fiveten是否小于0),如果不足则直接返回false,表示无法找零。
  • 如果循环结束,说明所有顾客都能得到正确的找零,返回true

注意点:

  • 代码中没有处理输入为空或非法输入的情况,实际应用中可能需要添加相应的错误处理。
  • 这个解法是基于贪心策略的,总是优先使用更小面额的钞票进行找零,以期望尽量减少找零所需的钞票数量。

406. 根据身高重建队列

假设有打乱顺序的一群人站成一个队列,数组 people 表示队列中一些人的属性(不一定按顺序)。每个 people[i] = [hi, ki] 表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。

请你重新构造并返回输入数组 people 所表示的队列。返回的队列应该格式化为数组 queue ,其中 queue[j] = [hj, kj] 是队列中第 j 个人的属性(queue[0] 是排在队列前面的人)。

示例 1:

输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
解释:
编号为 0 的人身高为 5 ,没有身高更高或者相同的人排在他前面。
编号为 1 的人身高为 7 ,没有身高更高或者相同的人排在他前面。
编号为 2 的人身高为 5 ,有 2 个身高更高或者相同的人排在他前面,即编号为 0 和 1 的人。
编号为 3 的人身高为 6 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
编号为 4 的人身高为 4 ,有 4 个身高更高或者相同的人排在他前面,即编号为 0、1、2、3 的人。
编号为 5 的人身高为 7 ,有 1 个身高更高或者相同的人排在他前面,即编号为 1 的人。
因此 [[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]] 是重新构造后的队列。
示例 2:

输入:people = [[6,0],[5,0],[4,0],[3,2],[2,2],[1,4]]
输出:[[4,0],[5,0],[2,2],[3,2],[1,4],[6,0]]

提示:

1 <= people.length <= 2000
0 <= hi <= 106
0 <= ki < people.length
题目数据确保队列可以被重建

class Solution {
    public int[][] reconstructQueue(int[][] people) {
        // 身高从大到小排(身高相同k小的站前面)
        Arrays.sort(people, (a, b) -> {
            if (a[0] == b[0]) return a[1] - b[1];   // a - b 是升序排列,故在a[0] == b[0]的狀況下,會根據k值升序排列
            return b[0] - a[0];   //b - a 是降序排列,在a[0] != b[0],的狀況會根據h值降序排列
        });

        LinkedList<int[]> que = new LinkedList<>();

        for (int[] p : people) {
            que.add(p[1],p);   //Linkedlist.add(index, value),會將value插入到指定index裡。
        }

        return que.toArray(new int[people.length][]);
    }
}

这段Java代码是用于解决“队列重建”问题的一个实现。给定一个二维数组 people,其中 people[i] = [hi, ki],表示第 i 个人的身高为 hi ,前面 正好 有 ki 个身高大于或等于 hi 的人。该函数的目标是根据这些信息重构队列,返回一个按正确顺序排列的数组。

代码解析:

  1. 排序:首先使用 Arrays.sort() 方法对 people 数组进行排序。排序的规则是首先按照身高 h 降序排列(即身高高的在前),当身高相同时,按照 k 值(前面比自己身高高或相等的人数)升序排列。这样保证了在身高相同的情况下,k 值较小的人会排在前面。

  2. 构造队列:创建一个 LinkedList(链表)que 用于存储重建后的队列。选择链表是因为它支持在列表的任何位置高效地插入元素,这正是本问题所需要的。

  3. 遍历排序后的数组:遍历排序后的 people 数组,对于每个人 p,使用 que.add(p[1], p) 将其插入到链表中正确的位置。这里的 p[1]k 值,即此人前面应该有多少个人比他高或等高,p 本身代表这个人(整个数组 [hi, ki])。

  4. 返回结果:最后,使用 toArray 方法将链表转换回二维数组,并返回结果。

总结:

该算法通过先排序后构建的方法,有效地解决了队列重建的问题。排序步骤确保了在插入过程中可以直接根据人的身高和前面人数的要求找到合适的位置,而链表的特性支持了在特定位置快速插入元素,从而保证了整体的时间效率。

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

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

相关文章

保姆级小白就业人工智能(视频+源码+笔记)

&#x1f345;我是小宋&#xff0c; Java学习AI&#xff0c;记录学习之旅。关注我&#xff0c;带你轻松过面试。提升简历亮点&#xff08;14个demo&#xff09; &#x1f345;我的java面试合集已有12W 浏览量。&#x1f30f;号&#xff1a;tutou123com。拉你进专属群。 ⭐⭐你的…

通义千问2(Qwen2)大语言模型在PAI-QuickStart的微调、评测与部署实践

Qwen2&#xff08;通义千问2&#xff09;是阿里云最近推出的开源大型语言模型系列&#xff0c;相比2月推出的Qwen1.5&#xff0c;Qwen2实现了整体性能的代际飞跃&#xff0c;大幅提升了代码、数学、推理、指令遵循、多语言理解等能力。其中&#xff0c;Qwen2系列包含5个尺寸的预…

群晖NAS部署在线PS工具Potopea并实现浏览器远程访问处理图片

文章目录 前言1. 部署Photopea2. 运行Photopea3. 群晖安装Cpolar4. 配置公网地址5. 公网访问测试6. 固定公网地址 前言 本文主要介绍如何在群晖NAS本地部署Potopea在线图片PS编辑工具&#xff0c;并结合cpolar内网穿透实现公网环境远程访问本地部署的Potopea处理图片. Photop…

《平衡小车控制系统》电子设计大赛校赛感悟

我们学校举行了一次电子设计大赛选拔赛&#xff0c;虽然我们在测试的时候全部都可以完成&#xff0c;最后考核的时候因为方案选择问题以及各种设计逻辑等原因没能成功晋级&#xff0c;但我能从这次备赛中学到很多东西&#xff0c;遂分享一下&#xff0c;与广大网友交流经验。&a…

嵌入式技术学习——c51单片机——蜂鸣器

一、蜂鸣器介绍 蜂鸣器时一种将电信号转化成声音信号的器件&#xff0c;常用来产生设备的按键音&#xff0c;报警音等提示信号。 蜂鸣器分为有源蜂鸣器&#xff0c;无源蜂鸣器 。 有源蜂鸣器&#xff1a;内部自带震荡源&#xff0c;将正负极街上直流电压即可持续发声&#x…

答应我,完成单位投稿任务用对的方法别让自己受投稿之苦

在这个信息爆炸的时代,单位的形象塑造与品牌传播已成为不可忽视的关键环节。作为单位的信息宣传员,我深知每一次对外发声的重要性,它不仅是展示我们工作成果的窗口,更是连接公众、塑造品牌形象的桥梁。然而,在传统的投稿方式中,尤其是依赖于邮箱投稿,我经历了太多次的挫败与无奈…

国际荐酒师香港协会受邀参加2024年美国独立日庆祝活动

国际荐酒师&#xff08;香港&#xff09;协会受邀参加2024年美国独立日庆祝活动促进世界酒中国菜的全球化发展 2024年6月18日&#xff0c;国际荐酒师&#xff08;香港&#xff09;协会大中华区驻广州办事处荣幸地接受了美国驻广州总领事馆 Nicholas Burns大使和Lisa Heller总领…

第十二章:会话控制

会话控制 文章目录 会话控制一、介绍二、cookie2.1 cookie 是什么2.2 cookie 的特点2.3 cookie 的运行流程2.4 浏览器操作 cookie2.5 cookie 的代码操作&#xff08;1&#xff09;设置 cookie&#xff08;2&#xff09;读取 cookie&#xff08;3&#xff09;删除 cookie 三、se…

使用 Web Serial API 在浏览器中实现串口通讯(纯前端)

文章目录 目的相关资料使用说明代码与演示总结 目的 串口是非常常用的一种电脑与设备交互的接口。目前在浏览器上直接使用电脑上的串口设备了&#xff0c;这篇文章将介绍相关内容。 相关资料 Web Serial API 相关内容参考如下&#xff1a; https://developer.mozilla.org/en…

【Java面试】二十、JVM篇(上):JVM结构

文章目录 1、JVM2、程序计数器3、堆4、栈4.1 垃圾回收是否涉及栈内存4.2 栈内存分配越大越好吗4.3 方法内的局部变量是否线程安全吗4.4 栈内存溢出的情况4.5 堆和栈的区别是什么 5、方法区5.1 常量池5.2 运行时常量池 6、直接内存 1、JVM Java源码编译成class字节码后&#xf…

七大黄金原油短线操作技巧与方法

1、研究K线组合 K线组合是几个交易日K线的衔接和联系&#xff0c;它无法掩饰地透露着黄金价格运行趋势的某种征兆。研究K线组合的深刻蕴含&#xff0c;感知其内在动意&#xff0c;把握黄金价格上涨征兆&#xff0c;可以大大提高上涨的概率。其实对许多诸如“强势整理”、“突破…

管道(channel)入门

管道&#xff08;Channel&#xff09; 1、管道本质就是一个数据结构-队列 2、数据是先进先出 3、自身线程安全&#xff0c;多协程访问时不需要加锁&#xff0c;channel本身就是线程安全的 4、管道有类型的&#xff0c;一个string的管道&#xff0c;只能存放string类型的数据 管…

vue3第四十节(pinia的用法注意事项解构store)

pinia 主要包括以下五部分&#xff0c;经常用到的是 store、state、getters、actions 以下使用说明&#xff0c;注意事项&#xff0c;仅限于 vue3 setup 语法糖中使用&#xff0c;若使用选项式 API 请直接查看官方文档&#xff1a; 一、前言&#xff1a; pinia 是为了探索 vu…

一文弄懂 Python os.walk(),轻松搞定文件处理和目录遍历

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ Python os 模块的 walk() 方法以自顶向下或自底向上的方式遍历指定的目录树&#xff0c;从而显示目录树中的文件名。对于目录树中的每个目录&#xff0c;os.walk() 方法都会产生一个包含目录路径、当前…

当同时绑定mousedown和mouseup时,不执行mouseup

问题描述&#xff1a; 当我同时给一个标签添加mousedown和mouseup两个鼠标事件&#xff0c;点击span的时候会触发mousedown事件&#xff0c;但是不会执行mouseup事件&#xff1b;但是注释图二中的setCloudControl方法又能触发mouseup。 后来查阅资料&#xff0c;发现是在封装a…

数据资产入表-数据分类分级标准-数据分级

前情提要&#xff1a;2021年9月1日&#xff0c;《中华人民共和国数据安全法》正式施行&#xff0c;明确规定“国家建立数据分类分级保护制度”&#xff0c;数据分级分类是数据安全管理的重要措施&#xff0c;它涉及到对数据资产的识别、分类和定级&#xff0c;是保障数据合规的…

VUE 项目用 Docker+Nginx进行打包部署

一、Docker Docker 是一个容器化平台&#xff0c;允许你将应用程序及其依赖项打包在容器中。使用 Docker&#xff0c;你可以创建一个包含 Vue.js 应用程序的容器镜像&#xff0c;并在任何支持 Docker 的环境中运行该镜像。 二、Nginx Nginx 是一个高性能的 HTTP 服务器和反向…

递归与回溯 || 排列问题

目录 前言&#xff1a; 全排列 题解&#xff1a; 全排列 II 题解&#xff1a; 子集 题解&#xff1a; 组合 题解&#xff1a; 组合总和 题解&#xff1a; 电话号码的字母组合 题解&#xff1a; 字母大小写全排列 题解&#xff1a; 优美的排列 题解&#xff1a;…

MySQL数据库回顾(1)

数据库相关概念 关系型数据库 概念: 建立在关系模型基础上&#xff0c;由多张相互连接的二维表组成的数据库。 特点&#xff1a; 1.使用表存储数据&#xff0c;格式统一&#xff0c;便于维护 2.使用SQL语言操作&#xff0c;标准统一&#xff0c;使用方便 SOL SQL通用语法 …

MySQL常见面试题自测

文章目录 MySQL基础架构一、说说 MySQL 的架构&#xff1f;二、一条 SQL语句在MySQL中的执行过程 MySQL存储引擎一、MySQL 提供了哪些存储引擎&#xff1f;二、MySQL 存储引擎架构了解吗&#xff1f;三、MyISAM 和 InnoDB 的区别&#xff1f; MySQL 事务一、何谓事务&#xff1…