数据结构与算法
文章平均质量分 86
学习数据结构、算法分析与设计
王清欢Randy
解决问题,担当责任,优雅生活。
展开
-
进阶数据结构 BTree 的插入与删除操作实现
在数据库系统和文件系统中,高效的数据组织与管理是关键之一。B-Tree(Balanced Tree)作为一种平衡搜索树结构,在这一领域发挥着重要作用。本文详细探讨了 B-Tree 的基本概念以及对其进行插入与删除操作的实现,旨在帮助读者理解 B-Tree 的工作原理以及如何有效地维护这种数据结构。原创 2024-02-26 08:00:00 · 5291 阅读 · 1 评论 -
LeetCode刷题笔记 优先搜索 图结构深度优先搜索
图结构深度优先搜索简介 深度优先搜索(depth-first seach,DFS)在搜索到一个新的节点时,立即对该新节点进行遍历;因此遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现。 对于树结构而言,由于总是对新节点调用遍历,因此看起来是向着 深 的方向前进,或者说是垂直方向。考虑如下一颗简单的树,由4 个节点构成共三层,其 DFS 过程如下图所示: 图通常有两种表示方法。假设图中一共有 n 个节点、m 条边。 第一种表示方法是邻接矩阵(adjacency matrix):我原创 2022-01-10 11:30:00 · 959 阅读 · 0 评论 -
LeetCode刷题笔记 优先搜索 树结构深度优先搜索
树结构深度优先搜索简介 深度优先搜索(depth-first seach,DFS)在搜索到一个新的节点时,立即对该新节点进行遍历;因此遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现。 对于树结构而言,由于总是对新节点调用遍历,因此看起来是向着 深 的方向前进,或者说是垂直方向。考虑如下一颗简单的树,由4 个节点构成共三层,其 DFS 过程如下图所示: 我们从 0 号节点开始遍历,假如遍历顺序是从左子节点到右子节点,那么按照优先向着深的方向前进的策略,假如我们使用递归实现,我们的遍原创 2022-01-09 11:45:00 · 1687 阅读 · 0 评论 -
LeetCode刷题笔记 优先搜索 网格结构深度优先搜索
深度优先搜索简介深度优先搜索(depth-first seach,DFS)在搜索到一个新的节点时,立即对该新节点进行遍历;因此遍历需要用先入后出的栈来实现,也可以通过与栈等价的递归来实现。二维数组深度优先搜索的一般写法: 一般来说,深度优先搜索类型的题可以分为主函数和辅函数,主函数用于遍历所有的搜索位置,判断是否满足开始搜索的条件,如果可以即在辅函数中进行搜索。 辅函数负责实现深度优先搜索过程。这一过程可以使用递归调用调用实现;当然,我们也可以使用栈(stack)实现深度优先搜索,与使用队列 (原创 2022-01-07 11:30:00 · 1020 阅读 · 0 评论 -
LeetCode刷题笔记 排序算法 桶排序
桶排序简介 桶排序、计数排序、计数排序,这三种排序算法的时间复杂度都是线性的,它们之所以能够做到线性的时间复杂度,主要原因是这几个算法是非基于比较的排序算法,不涉及元素之间的比较操作。 这几种排序算法的时间复杂度虽然低,但是对要排序的数据要求比较苛刻,所以关键是要知道这些排序算法的适用场景。算法思想: 通排序,顾名思义就是为一个值设立一个桶,将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行排序。桶排序完之后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了。 例如[25原创 2021-12-30 11:30:00 · 939 阅读 · 1 评论 -
LeetCode刷题笔记 排序算法 归并排序
归并排序简介算法思想: 归并排序的核心思想是采用分治策略,将整个数组的排序任务分类为两个子问题,前一半排序和后一半排序,然后整合两个有序部分完成整体排序。即把数组分为若干个子序列,直到单个元素组成一个序列,然后将各阶段得到的序列组合在一起得到最终完整排序序列。 归并排序任务可以如下分治完成:1. 把前一半排序2. 把后一半排序3. 把两半归并到一个新的有序数组,然后再拷贝回原数组,排序完成。执行样例:输入:[29,10,14,37,14,25,10]算法实现:// 将数组 a 的原创 2021-12-28 11:45:00 · 1324 阅读 · 0 评论 -
LeetCode刷题笔记 排序算法 快速排序
快速排序简介算法思想: 快速排序是对冒泡排序的一种改进,其核心算法思想是:使用基准将要排序的数据分割成小于基准和大于基准的两部分;然后在被分割的两个部分中递归按基准划分的步骤,最终递归到一个部分仅有一个元素组成,此时数组排序完成。 算法实现过程中,在使用快排之前可以将数组打乱,因为快排是不稳定的算法,在原数组大部分元素是有序的情况下效率提升不明显。 实现快排步骤如下:先选取基准,可以以序列第一个元素作为基准然后使用碰撞指针遍历数组,从指向数组尾部的指针 tail 开始移动,将数组尾部小于原创 2021-12-27 12:44:43 · 1107 阅读 · 0 评论 -
LeetCode刷题笔记 二分查找 局部有序
二分查找的局部有序情况 我们已经知道二分查找是一种在有序数组中查找某一特定元素的查找算法。 那如果一个数组不是整体有序,而是局部有序呢?这时我们就可以通过分治策略,我们在局部有序的区间内进行二分查找,然后合并各个局部结果组成整体结果。153 寻找旋转排序数组中的最小值已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次的结果为数组 [a[n-1], a[0], a[1], a[2原创 2021-12-19 11:45:00 · 1670 阅读 · 0 评论 -
LeetCode刷题笔记 二分查找 边界收缩
二分查找的边界值 二分查找很简单,但是也有它的难点,其难点就在于在判定条件和边界值的选择上,很容易就会导致越界或者死循环的情况。 对于循环的判定条件,如果查找区间是闭区间[left, right],则判定条件要设为while(left<=right),该判定条件是在出现left > right的情况下终止循环;如果这种闭区间查找区间下使用while(left < right)作为判定条件,该判定条件是在出现left >= right的情况下终止循环,这种情况就没有查找left原创 2021-12-17 11:30:00 · 1591 阅读 · 0 评论 -
LeetCode刷题笔记 二分查找 基础应用
二分查找简介 二分查找也常被称为二分法或者折半查找,它是一种在有序数组中查找某一特定元素的查找算法。这种查找方法将查找的时间复杂度从原本的线性时间提升到了对数时间范围,大大缩短了搜索时间。对于一个长度为 O(n) 的数组,二分查找的时间复杂度为 O(log n)。 举例来说,给定一个排好序的数组 {3,4,5,6,7},我们希望查找 4 在不在这个数组内。第一次折半时考虑中位数 5,因为 5 大于 4, 所以如果 4 存在于这个数组,那么其必定存在于 5 左边这一半。于是我们的查找区间变成了 {3,原创 2021-12-16 10:31:07 · 2724 阅读 · 0 评论 -
LeetCode刷题笔记 双指针 滑动窗口
滑动窗口滑动窗口:两个指针指向同一线性表,遍历方向相同,且两个指针起点不同,则会形成一个滑动窗口,两个指针以不同的策略移动,直到两个指针的值相等或满足其他特殊条件为止。76 最小覆盖子串给定一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" 。输入是两个字符串 S 和 T,输出是一个 S 字符串的子串。输入:s = “ADOBECODEBANC”, t = “ABC”输出:“BANC”解释:S 中同时原创 2021-12-05 11:30:00 · 1980 阅读 · 0 评论 -
LeetCode刷题笔记 双指针 快慢指针
快慢指针快慢指针 Equi-directional:两个指针指向同一线性表,遍历方向相同,且两个指针起点可以相同,也可以不同形成一个滑动窗口,两个指针以不同的策略移动,直到两个指针的值相等或满足其他特殊条件为止。142 环形链表 II给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 n原创 2021-12-04 13:35:38 · 1977 阅读 · 0 评论 -
LeetCode刷题笔记 双指针 碰撞指针
碰撞指针简介碰撞指针 Opposite directional:两个指针指向同一线性表,但是遍历方向相反,一个指针指向开头,另一个指向末尾,它们相向移动直到相遇或满足其他特殊条件为止344 反转字符串编写一个函数,其作用是将输入的字符串反转过来。输入一个字符数组,输出将其反转的字符数组输入:s = [“h”,“e”,“l”,“l”,“o”]输出:[“o”,“l”,“l”,“e”,“h”]解析: 本题使用双指针可以快速简单地解决。我们定义一对碰撞指针分别指向字符数组的头和尾,然后循环执行原创 2021-12-02 10:45:21 · 2465 阅读 · 0 评论 -
LeetCode刷题笔记 双指针 基础应用
双指针简介 双指针的用途:双指针主要用于单循环遍历线性表数据结构,两个指针指向不同的元素,从而协同完成任务(通常双指针分别指向元素比较,或者两元素联合与某一条件比较) 双指针的特点:不管数据输入是字符串、数组还是链表,使用一般方法的遍历方法时间复杂度度在O(n3)*和*O(n2)使用双指针对其进行遍历的平均时间复杂度为O(nlogn),最好的情况下时间复杂度为O(n) 两种特殊形式的双指针碰撞指针 Opposite directional:两个指针指向同一线性表,但是遍历方向相反,一个指针指原创 2021-11-30 10:41:40 · 2595 阅读 · 0 评论 -
LeetCode刷题笔记 图 拓扑排序
拓扑排序简介 拓扑排序(topological sort)是一种常见的,对有向无环图排序的算法。给定有向无环图中的 N 个节点,我们把它们排序成一个线性序列;若原图中节点 i 指向节点 j,则排序结果中 i 一定在 j 之前。拓扑排序的结果不是唯一的,只要满足以上条件即可。210 课程表 II给定 N 个课程和这些课程的前置必修课,求可以一次性上完所有课的顺序输入是一个正整数,表示课程数量,和一个二维矩阵,表示所有的有向边,例如 [1,0] 表示上课程 1 之前必须先上课程 0。输出是一个一维数组原创 2021-11-28 11:30:00 · 2168 阅读 · 0 评论 -
LeetCode刷题笔记 图 二分图
二分图简介 二分图算法也称为染色法,是一种广度优先搜索。如果可以用两种颜色对图中的节点进行着色,并且保证相邻的节点颜色不同,那么图为二分。 二分图定义:如果能将一个图的节点集合分割成两个独立的子集 A 和 B ,并使图中的每一条边的两个节点一个来自 A 集合,一个来自 B 集合,就将这个图称为 二分图 。785 判断二分图给定一个图,判断其是否可以二分输入是邻接链表表示的图(如位置 0 的邻接链表为 [1,3],表示 0 与 1、0 与 3 相连);输出是一个布尔值,表示图是否二分。输入:原创 2021-11-27 10:30:00 · 2224 阅读 · 0 评论 -
LeetCode刷题笔记 二叉树 二叉搜索树的操作
669 修剪二叉搜索树 给定一个二叉查找树和两个整数 L 和 R,且 L < R,试修剪此二叉查找树,使得修剪后所有节点的值都在 [L, R] 的范围内。 输入是一个二叉查找树和两个整数 L 和 R,输出一个被修剪好的二叉查找树。输入:root = [3,0,4,null,2,null,null,1], low = 1, high = 3输出:[3,2,null,1]解析: 利用二叉查找树的大小关系,我们可以很容易地利用递归进行树的处理。 递归遍历每一个节点,如果当前值大于原创 2021-11-21 11:30:00 · 2551 阅读 · 0 评论 -
LeetCode刷题笔记 二叉树 二叉搜索树的属性
二叉查找树简介 二叉查找树 / 二叉搜索树(Binary Search Tree, BST)是一种特殊的二叉树:对于每个父节点,其左子节点的值小于等于父结点的值,其右子节点的值大于等于父结点的值。因此对于一个二叉查找树,我们可以在 O(nlogn) 的时间内查找一个值是否存在:从根节点开始,若当前节点的值大于查找值则向左下走,若当前节点的值小于查找值则向右下走。同时因为二叉查找树是有序的,对其中序遍历的结果即为排好序的数组。 一个二叉查找树的实现如下:template <class T&g原创 2021-11-19 11:45:00 · 2958 阅读 · 0 评论 -
LeetCode刷题笔记 二叉树 层次遍历
通常使用广度优先搜索进行层次遍历。注意,不需要使用两个队列来分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。102 二叉树的层序遍历实现二叉树的层序遍历输入一个二叉树,输出一个二维数组,表示二叉树层序遍历的结果输入:[3,9,20,null,null,15,7] 3/ \9 20 / \15 7输出:[[3],[9,20],[15,7]]解析原创 2021-11-15 20:00:00 · 2587 阅读 · 0 评论 -
LeetCode刷题笔记 二叉树 前中后序遍历
二叉树前中后序遍历简介 前序遍历、中序遍历和后序遍历是三种利用深度优先搜索遍历二叉树的方式。它们是在对节点访问的顺序有一点不同,其它完全相同。例如层次遍历得到的二叉数为 [1,2,3,4,5,6,7] NLR 其前序遍历结果为 [1,2,4,5,3,6,7],先遍历父结点,再遍历左结点,最后遍历右节点void preorder(TreeNode* root) { visit(root); preorder(root->left); preorder(root->原创 2021-11-17 12:56:31 · 2736 阅读 · 0 评论 -
LeetCode刷题笔记 二叉树 路径总和
112 路径总和给定一个二叉树root和一个值 sum ,判断是否有从根节点到叶子节点的节点值之和等于 sum 的路径。输入一个二叉树和一个给定整数,输出一个布尔值,表示有没有条满足条件的路径。输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22输出:true解释:等于目标和的根节点到叶节点路径为[5,4,11,2]。解析:注意叶子节点是指没有子节点的节点,路径只能从父节点到子节点,不能从子节点到父节点。对原创 2022-02-28 20:04:47 · 4312 阅读 · 0 评论 -
LeetCode刷题笔记 二叉树 二叉树的操作
226 翻转二叉树翻转一棵二叉树输入一棵二叉树,输出一棵左右子树的位置跟输入正好相反的二叉树输入: 4 / \ 2 7/ \ / \1 3 6 9输出: 4 / \ 7 2/ \ / \9 6 3 1解析: 本题是一道经典的递归问题,我们采用自下而上的递归策略,从叶子节点开始交换左右节点。如果当前根节点 root 的左右子树都已经完成了翻转,那么仅需要交换两个子树的位置即可,即交换 root 左右节原创 2021-11-15 09:54:59 · 2538 阅读 · 0 评论 -
LeetCode刷题笔记 二叉树 二叉树的属性
最为常见的树就是二叉树,这种树的每个节点最多有两个子节点,二叉树可以看成是单链表的升级版,因为他和链表的主要区别就是多了一个子节点的指针。 Definition for a binary tree node. struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode原创 2021-11-13 15:30:00 · 2588 阅读 · 0 评论 -
LeetCode刷题笔记 链表 遍历链表
160 相交链表给定两个链表,判断它们是否相交于一点,并求这个相交节点。输入是两条链表,输出是一个节点。如无相交节点,则返回一个空节点。输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3输出:Intersected at ‘8’解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1原创 2021-11-11 11:00:00 · 3120 阅读 · 0 评论 -
LeetCode刷题笔记 链表 链表的基础操作
链表简介 链表是由节点和指针构成的数据结构,每个节点存有一个值,和一个指向下一个节点的指针,因此很多链表问题可以用递归来处理。不同于数组,链表并不能直接获取任意节点的值,必须要通过指针找到该节点后才能获取其值。同理,在未遍历到链表结尾时,我们也无法知道链表的长度,除非依赖其他数据结构储存长度。原创 2021-11-09 11:08:08 · 3935 阅读 · 0 评论 -
LeetCode刷题笔记 字符串 字符串匹配
28 实现 strStr()判断一个字符串是不是另一个字符串的子字符串,并返回其位置。输入一个母字符串和一个子字符串,输出一个整数,表示子字符串在母字符串的位置,若不存在则返回-1。输入:haystack = “hello”, needle = “ll”输出:2解析: 解决本题一种简单的思路是暴力匹配:首先将子串和母串左端对齐;然后逐个比较对应的字符,如果发现不匹配则将子串开始匹配位置相对于母串后移动一位,同时将比较指针回溯到子串头部;重复匹配过程,直到找到对应子串,不存在则返回 -1。原创 2021-11-05 13:00:00 · 3910 阅读 · 1 评论 -
LeetCode刷题笔记 字符串 回文字符串
125 验证回文串给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。输入一个字符串,输出一个布尔值表示该字符串是否为回文串输入: “A man, a plan, a canal: Panama”输出: true解释:“amanaplanacanalpanama” 是回文串解析: 回文串一般都可以采用双指针从两头向中间检验,或者采用中心扩展法从中间向两头验证是否为回文串。 本题可以采用双指针的策略,从字符串首尾两端逐个字符检验。但是本题中给出的字符串有许多原创 2021-11-03 18:00:00 · 3708 阅读 · 0 评论 -
LeetCode刷题笔记 字符串 字符串比较
242 有效的字母异位词判断两个字符串包含的字符是否完全相同。输入两个字符串,输出一个布尔值,表示两个字符串是否满足条件。输入: s = “anagram”, t = “nagaram”输出: true解析: 可以利用哈希表或者数组统计两个数组中每个数字出现的频次,若频次相同,则说明它们包含的字符完全相同。 为了降低空间复杂度,我们可以仅采用一个哈希表或数组记录 S 中字符的频次,然后减去 T 中对应字符出现的频次,如果最终该频次为 0 则该字符在 S 和 T 中个数相等,如果最终S和原创 2021-11-01 13:12:50 · 3340 阅读 · 0 评论 -
LeetCode刷题笔记 标准模板库巧解算法题 优先队列
优先队列简介 优先队列(priority queue)可以在 O(1) 时间内获得最大值,并且可以在 O(log n) 时间内取出最大值或插入任意值。 优先队列常常用堆(heap)来实现。堆是一个完全二叉树,其每个节点的值总是大于等于子节点的值。实际实现堆时,我们通常用一个数组而不是用指针建立一个树。这是因为堆是完全二叉树,所以用数组表示时,位置 i 的节点的父节点位置一定为 i/2,而它的两个子节点的位置又一定分别为 2i 和 2i+1。 以下是堆的实现方法,其中最核心的两个操作是上浮和下沉:原创 2021-10-23 18:00:00 · 3532 阅读 · 0 评论 -
LeetCode刷题笔记 标准模板库巧解算法题 哈希表
哈希表简介 哈希表,又称散列表,使用 O(n) 空间复杂度存储数据,通过哈希函数映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。 C++ 中的哈希集合为 unordered_set,可以查找元素是否在集合中。如果需要同时存储键和值,则需要用 unordered_map,可以用来统计频率,记录内容等等。如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为原创 2021-10-24 10:30:00 · 3471 阅读 · 2 评论 -
LeetCode刷题笔记 标准模板库巧解算法题 前缀和
前缀和常用于解决 区域和检索 相关的题型 一维的前缀和,二维的积分图,都是把每个位置之前的一维线段或二维矩形预先存储,方便加速计算。如果需要对前缀和或积分图的值做寻址,则要存在哈希表里;如果要对每个位置记录前缀和或积分图的值,则可以储存到一维或二维数组里,也常常伴随着动态规划。303 区域和检索设计一个类,使得其能够快速查询给定整数数组 nums中,求数组从索引 i 到 j(i ≤ j)范围内元素的总和,包含 i、j两点。NumArray 类的调用样例:输入:[“NumArray”, “su原创 2021-10-26 11:00:00 · 3297 阅读 · 0 评论 -
LeetCode刷题笔记 标准模板库巧解算法题 多重集合
332 重新安排行程给定一个人坐过的一些飞机的起止机场,已知这个人从 JFK 起飞,那么这个人是按什么顺序飞的;如果存在多种可能性,返回字母序最小的那种。输入是一个二维字符串数组,表示多个起止机场对子;输出是一个一维字符串数组,表示飞行顺序。输入:tickets = [[“JFK”,“SFO”],[“JFK”,“ATL”],[“SFO”,“ATL”],[“ATL”,“JFK”],[“ATL”,“SFO”]]输出:[“JFK”,“ATL”,“JFK”,“SFO”,“ATL”,“SFO”]解释:另一原创 2021-10-25 16:00:00 · 3269 阅读 · 0 评论 -
LeetCode刷题笔记 标准模板库巧解算法题 单调栈
单调栈通过维持栈内值的单调递增(递减)性,在整体 O(n) 的时间内处理需要大小比较的问题。739 每日温度给定每天的温度,求对于每一天需要等几天才可以等到更暖和的一天。如果该天之后不存在更暖和的天气,则记为 0。输入是一个一维整数数组,输出是同样长度的整数数组,表示对于每天需要等待多少天。输入: temperatures = [73,74,75,71,69,72,76,73]输出: [1,1,4,2,1,1,0,0]解析: 本题可以通过维持一个单调递减的栈,表示每天的温度;而本题要求的原创 2021-10-22 14:45:00 · 3624 阅读 · 0 评论 -
LeetCode刷题笔记 标准模板库巧解算法题 栈和队列
232 用栈实现队列尝试使用栈(stack)来实现队列(queue)。实现 MyQueue 类:void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移除并返回元素int peek() 返回队列开头的元素boolean empty() 如果队列为空,返回 true ;否则,返回 false解析: 本题可以使用两个方向相反的栈实现一个队列如下图所示,其中箭头表示元素 pop 方向 使用两个栈的目的是:为了达到先入先出的效果,需要有一个栈用来翻转原创 2021-10-21 14:00:00 · 3555 阅读 · 0 评论 -
LeetCode刷题笔记 标准模板库巧解算法题 数组
C++ STL 容器 容器是可容纳各种数据类型(基本数据类型、对象等)的通用数据结构,都是类模板,分为三种类型:顺序容器:vector, deque, list关联容器:set, multiset, map, multimap容器适配器:stack, queue, priority_queue顺序容器: 顺序容器是非排序的,而且其元素的插入位置与元素自身的值无关,数组便于查找,链表便于操作。vector #include <vector> 一维动态数组:其元素在内存中是连原创 2021-10-20 11:00:17 · 3753 阅读 · 0 评论 -
LeetCode刷题笔记 位运算巧解算法题 二进制特性
利用二进制的一些特性,可以把位运算使用到更多问题上。例如,可以利用二进制和位运算输出一个数组的所有子集。假设有一个长度为 n 的数组,可以生成长度为 n 的所有二进制,1 表示选取该数字,0 表示不选取。这样就获得了 2^n 个子集。342 4的幂给定一个整数,判断它是否是 4 的次方。输入是一个整数,输出是一个布尔值,表示判断结果。输入:n = 16输出:true解析: 本题可以采用按位与运算简单实现判断数是否为4的幂。如果 n 是 4 的幂,那么 n 的二进制表示中有且仅有一个原创 2021-10-19 15:30:00 · 3800 阅读 · 0 评论 -
LeetCode刷题笔记 位运算巧解算法题 妙用异或运算
异或运算的特性十分重要 (1) x ^ 0000 = x; (2) x ^ 1111 = ~x; (3) x ^ x = 0,它的这些特性被广泛用于取返、去重等问题中。476 数字的补数给你一个 正 整数 num ,输出它的补数。补数是对该数的二进制表示取反。输入一个整数,输出一个整数表示原整数的补数输入:num = 5输出:2解释:5 的二进制表示为 101(没有前导零位),其补数为 010。所以你需要输出 2 。解析: 看到二进制位取返就可以想到异或运算x^1111 = ~x,原创 2021-10-17 16:00:00 · 3765 阅读 · 0 评论 -
LeetCode刷题笔记 位运算巧解算法题 位运算基础
位运算是算法题里比较特殊的一种类型,它们利用二进制位运算的特性进行一些奇妙的优化和计算。常用的位运算符号包括:“∧” 按位异或、“&” 按位与、“|” 按位或、“∼” 取反、“<<” 算术左移和 “>>” 算术右移。以下是一些常见的位运算特性:异或与或x ^ 0000 = xx & 0000 = 0x | 0000 = xx ^ 1111 = ~xx & 1111 = xx | 1111 = 1111x ^ x原创 2021-10-15 15:29:46 · 3892 阅读 · 0 评论 -
LeetCode刷题笔记 算法中的数学问题 随机数问题
384 打乱数组给定一个数组,要求实现两个指令函数。第一个函数 shuffle() 可以随机打乱这个数组,第二个函数 reset() 可以恢复原来的顺序。输入是一个存有整数数字的数组,和一个包含指令函数名称的数组。输出是一个二维数组,表示每个指令生成的数组。输入: [“Solution”, “shuffle”, “reset”, “shuffle”] [[[1, 2, 3]], [], [], []]输出: [null, [3, 1, 2], [1, 2, 3], [1, 3, 2]]解释:Sol原创 2021-10-14 11:45:00 · 3510 阅读 · 0 评论 -
LeetCode刷题笔记 算法中的数学问题 数字处理问题
238 除自身以外数组的乘积给定一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。输入一个数组,输出一个数组,其中每个元素数值为除本身之外所有元素的乘积输入: [1,2,3,4]输出: [24,12,8,6]解析: 本题与135题分糖果相似,可以先从左到右计算当前元素左侧所有元素的乘积,然后从右到左计算当前元素右侧所有元素的乘积,再将两个元素乘积相乘得到最终结果。原创 2021-10-12 18:15:00 · 3076 阅读 · 0 评论