LeetCode Hot100 刷题笔记:思路拆解 + Java 易错点与语法积累(持续更新)

LeetCode Hot100 刷题笔记:思路拆解 + Java 易错点与语法积累(持续更新)

文章目录


前言

本文是我在做LeetCode Hot100过程中,依次记录的部分题目的思路,以及一些可以积累的语法或易错点,如有错误,敬请指正~/抱拳 (下面第n题是按顺序排的,题目名字前的数字对应官网中的题号)


一、哈希图

HASH(key)= key MOD p;
解决哈希冲突的方法有:线性探测、拉链法等。

第一题(1两数之和)
  1. unordered_map<int, int>,定义哈希图
  2. nums.size(),计算vector< int >长度
  3. hashtable.find()搜索,hashtable.end()搜索不到的返回;it承担迭代结果
  4. hashtable[nums[i]] = i,哈希表赋值
第二题(49字母异位词分组)
  1. .emplace_back(str)等价于mp[key].push_back(str);但 emplace_back 更高效(原地构造)。
  2. 现代 C++ 的理念就是:只要类型太复杂,就用 auto。让编译器推导。
  3. string key = str;用key来代替str否则原字符串会被改变
  4. 在迭代器里推荐 ++it

sort (key.begin(), key.end());可用于对字符串的排序,复杂度为O(n log n),这是升序排序,此外还有:sort(v.begin(), v.end(), greater());降序排序;自定义比较器(return后的内容可根据实际情况替换):

自定义比较器举例
第三题(128最长连续序列)
  1. unordered_set st(nums.begin(), nums.end());构建了一个哈希集合,且自动去重
  2. const string& s,可用来避免昂贵的拷贝

一些哈希相关的函数:①count(x),判断元素是否存在(速度比.contains()快得多) ②find(x),同上,但可取得迭代器

在这里插入图片描述


③size()大小 ④empty()判断空 ⑤insert()插入

二、双指针

第四题(238移动零)
  1. vector的长度:nums.size()
  2. swap (nums[left], nums[right]);交换数组的两个元素
第五题(11盛最多水的容器)
  1. r = height.size()- 1;
  2. - -r;右指针是递减的
  3. 为何用题解方法消耗内存较大?

思路关键:每次移动对应高度较小的那一个指针

在这里插入图片描述
第六题(15三数之和)
  1. 不重复意味着要排序
  2. ans.push_back({nums[first], nums[second], nums[third]}); {a, b, c} 是一个 initializer_list,它会自动构造成一个vector, 然后传给 ans.push_back
  3. 主要思路就是,首先排序,然后固定first,second和third的变动是并列的

从下面开始用Java写了

第七题(42接雨水)
  1. 思路:计算每一个i对应的leftMax和rightMax,这决定了该位置能积攒多少水,动态规划
  2. for (int i = n-2; i >= 0; i–)rightMax应该从右往左遍历2,即递减
  3. leftMax[i] = Math.max(leftMax[i-1], height[i]);最大值比较包含i位置自身
  4. int[] a = new int[n];记得限定长度
  5. 数组n.length

三、滑动窗口

第八题(3无重复字符的最长子串)
  1. Set occ = new HashSet();定义哈希表
  2. 初始化rk = -1,且在滑动过程中是一个单增的量,因为右指针扫过的地方已经确定无重复,只需向后扩张
  3. 字符串s.length();s.charAt(i)
  4. occ.remove(s.charAt(i-1)); occ.add(s.charAt(rk + 1)); occ.contains(s.charAt(rk + 1))几个相关的哈希表的函数
  5. rk - i +1这样比occ.size()效率高

新增使用HashMap的方法(上面是使用集合的做法):

在这里插入图片描述
第九题(438找到字符串中所有字母异位词)
  1. 题解是利用i的循环代替了显式的l或r指针
  2. return new ArrayList< Integer>();返回列表为空的情况,方便调用方再使用.size()、.add()等函数
  3. 第0遍循环也要记录s的字母数量:++sCount[s.charAt(i) - ‘a’];

下面语句中的两个函数,能够分别解决快速比较和动态控制ans长度的问题:

在这里插入图片描述

另外,List是接口,ArrayList是实现类,该接口被限制
只暴露add、get、size、remove,而不暴露内部实现或ArrayList的私有函数。类似写法 (注意字母的大小写规律)

在这里插入图片描述


在这里插入图片描述

四、子串

第十题(560和为K的子数组)
  1. mp.getOrDefault(pre, 0) + 1:用这个函数的原因:如果pre没有出现果,mp.get(pre) 会返回 null,null+1会崩溃

此题的关键思路是:

在这里插入图片描述

首先记录一下,这个题目看完思路以后自己手搓,除了定义HashMap和contaisKey函数名写错了,其他全写对了,恭喜我自己!

在这里插入图片描述
第十一题(239滑动窗口最大值)
  1. 我学习的是单调队列的思路,相关函数有:① deque.isEmpty();② deque.peekLast();③ deque.pollLast();④ deque.offerLast(i);⑤ deque.peekFirst();⑥ deque.pollFirst();
  2. 注意:int[] ans = new int[n - k + 1];不要忘记new

Java是面向实现的编程:

在这里插入图片描述
第十二题(76最小覆盖子串)
  1. 首先需要注意,该题目包含大小写字母;其次,思路为:右指针不断右移先找到涵盖了t字符串的位置,然后左指针左移,缩小窗口范围找到最短字符串
  2. s.substring(ansLeft, ansRight + 1):加一的原因是,Java的该函数为左闭右开区间

遍历一个String的各个字符串:

在这里插入图片描述

五、普通数组

第十三题(53最大子数组和)
  1. 动态规划法:pre = Math.max(pre + x, x); 这样才能以x为新的字符串起点(而不是pre = Math.max(pre + x, pre);)
  2. Math.max()函数的利用
  3. 分治法?线段树的概念
第十四题(56合并区间)
  1. merged.add(new int[]{L, R}); 后面是数组的初始化列表
  2. return merged.toArray(new int[merged.size()][ ]); 最后的返回值应该转换成题目要求的数据类型

思路关键:排序(可行性由反证法证明),然后遍历区间,根据已有的最末端点与当前区间的起点比较,判断是否合并,积累comparator函数的写法(Comparator函数是写在Arrays.sort的括号里的)

Comparator函数是写在Arrays.sort的括号里的
第十五题(189轮转数组)
  1. 选择的是数组翻转的方法
  2. nums需要通过参数传给reverse函数,且在Java中传入后进行reverse是可以改变原数组的,传入的是引用
第十六题(238除自身以外数组的乘积)
  1. 思路:分别后向、前向计算得到前缀乘积和后缀乘积L、R数组,再分别相乘得ans
  2. 若想要空间复杂度为O(1),则用answer数组代替L数组,同时取消R数组,用R来记录即可
第十七题(41缺失的第一个正数)
  1. 注意这里的实现:我们给数组中的第 ∣x∣−1 个位置的数添加一个负号,注意如果它已经有负号,不需要重复添加。nums[num - 1] = -Math.abs(nums[num - 1]);
  2. 思路二置换法:将nums[i]换到下标为nums[i]-1的位置,最多替换N次;注意nums[i] =x=nums[x−1]的死循环

思路一直接上图:

在这里插入图片描述

六、矩阵

第十八题(73矩阵置零)
  1. 似懂非懂:为什么使用一个标记变量需要倒序,而使用两个标记变量的方法不用考虑这一点呢?
第十九题(54螺旋矩阵)

按层模拟法:

在这里插入图片描述


这个方法注意:在每层向左和向上遍历时,要把for循环放入 if (left < right && top < bottom) 条件判断中,不是为了越界判断,而是为了防止重复输出。
另外,此题注意最初的矩阵判空。

模拟法可借鉴之处:int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
以及对方向的判断,如图:

在这里插入图片描述
第二十题(48旋转图像)

法二:用翻转代替旋转
因为这样的操作可以得到关键等式

在这里插入图片描述

法一:原地旋转法
处于循环中的四项:

在这里插入图片描述


偶数时枚举n2/4=(n/2)×(n/2)个位置;
奇数时枚举 (n2−1)/4=((n−1)/2)×((n+1)/2) 个位置;
最后两种情况在代码中可以统一为:

在这里插入图片描述
第二十一题(240搜索二维矩阵Ⅱ)
  1. 法二:“Z”字形查找,从右上角为起点(此时它是这一行最大的,这一列最小的)

法一:逐行进行二分查找
这里积累向其他函数传递一行数据的简洁写法:

在这里插入图片描述

七、链表

第二十二题(160相交链表)
  1. 法一:将链表A存入名为visited的哈希表中,逐个判断链表B的各个节点是否在哈希表中:visited.contains(temp);注意:temp为ListNode类型,比较的是是否为同一个节点而不仅仅是val是否相同

法二:双指针的方法,过于巧妙:

在这里插入图片描述
第二十三题(206反转链表)
  1. 迭代法,注意:要用next = cur.next将下一个节点存储下来
  2. 递归法,结束条件判断为 if (head == null || head.next == null)
    递归找到新的头,然后head.next.next = head;
第二十四题(234反转链表)
  1. 快慢指针,最后还原链表
第二十五题(141环形链表)
  1. 快慢指针,根据结果来看,把两个指针最初都放在head再移动和比较效率会更高
第二十六题(142环形链表Ⅱ)
  1. 快慢指针

关键公式:含义是从相遇点,再走几圈和c步,和从head出发的节点会在环的入口相遇

在这里插入图片描述
第二十七题(21合并两个有序链表)
  1. 递归法:关键语句:l1.next = mergeTwoLists(l1.next, l2);
  2. 迭代法:使用一个prev(初始化语句:ListNode prehead = new ListNode(-1);)来记录头节点,最终返回 return prehead.next;
    合并后至多有一个不为空 prev.next = l1 == null ? l2 : l1;
第二十八题(2两数相加)
  1. 若一个数(链表)长度较短,则相当于后面有好多0
  2. 最后如果carry>0,则需要多加一位
  3. l1进行.next操作时需要判断是否为空,因为为空时也在循环里,当成0处理了
第二十九题(2两数相加)
  1. 栈的方法:加入dummy(用的是哑节点的方法)的目的是统一删除头节点和后续节点的操作。定义额外的哑节点的方法(ListNode dummy = new ListNode(0, head);)
    栈保存的是对节点的引用(其地址,相当于这个节点多了一条被指向的线)
  2. 双指针的方法:加入哑节点后,先让first指针走n下,然后让first和second一起走,直到second走到要删除的前一个节点的位置
第三十题(24两两交换链表中的节点)
  1. 加入哑节点后,在temp.next != null && temp.next.next != null的条件下进行交换即可
第三十一题(25K个一组翻转链表)

思路不难,就是代码复杂,这里的翻转链表和前面的思路一样吗?

在这里插入图片描述
第三十二题(138随机链表的复制)

这里直接放了哈希表法的代码,因为对这个题的理解还不是很深

在这里插入图片描述
第三十三题(148排序链表)
  1. 快慢指针找中点
  2. 左右子链表分别递归调用sortList()
  3. 最后记得加上剩余的长度h.next = left == null ? right : left;
第三十四题(23合并K个升序链表)
  1. 顺序合并、分治合并
  2. 使用优先队列合并:定义一个类来存储状态用以比较节点值的大小,使用接口 class Status implements Comparable,并在后面定义比较函数:public int compareTo(Status status2);
    for (ListNode node: lists) 取出每个链表的第一个节点,然后从最小堆中取出堆顶 queue.poll();然后放入最小值节点的下一个 queue.offer(new Status(f.ptr.next.val, f.ptr.next))
  3. 复杂度的分析没明白……
第三十五题(146LRU缓存)
  1. 这道题目代码写起来不难,就是思路很新之前没有学过,然后会有很多小细节

唯一一个私有函数有返回值类型的,因为要将其用在删除cache对应的一对映射中

在这里插入图片描述


在这里插入图片描述

将新节点插入链表的同时要更新哈希表,删除同理(cache.remove())

在这里插入图片描述

初始化头尾哑节点要记得把他们连起来(后两句)

在这里插入图片描述

无参构造函数和带参构造函数 (注意:构造函数无返回值类型)

在这里插入图片描述

八、二叉树

第三十六题(94二叉树的中序遍历)
  1. 递归代码很简单,这里用的是迭代的方法“颜色标记法”
  2. 一些语法知识:
    ①Deque stack = new LinkedList<>(); 既可以当作栈(stack.push(x);stack.pop())也可以当作队列(deque.offer(x);deque.poll()),关键是看使用了什么方法
    ②构造函数前是否加 public 根据需求

关键代码:

在这里插入图片描述
第三十七题(104二叉树的最大深度)
  1. 深度优先遍历:利用递归
  2. 广度优先遍历:利用队列,逐层加入所有节点,统一弹出上层所有节点
  3. Queue与Deque的区别:
    ①Queue是单向队列,方法:offer(x); poll(); peek()。使用场景:二叉树层次遍历、拓扑遍历
    ②Deque是两头都能进出的双端队列,方法:addFirst(e) / addLast(e) / pollFirst() / pollLast();以及栈语义:push(e) / pop()。使用场景:当栈用、双端操作(滑动窗口、单调队列)
第三十八题(226翻转二叉树)
  1. 深度和广度两种方法
第三十九题(101对称二叉树)

迭代法:如果比较的两个位置都为空,应该continue;而不是返回true

在这里插入图片描述


关键语句:

在这里插入图片描述

递归法:关键语句

在这里插入图片描述
第四十题(543二叉树的直径)
  1. 递归计算每一个节点的L+R
第四十一题(102二叉树的层序遍历)
  1. 广度优先遍历即可
  2. List<List> ans = new ArrayList<List>(); 这种定义方式只关心<>中是“List< Integer >”,而不是实现类
第四十二题(108将有序数组转换为二叉搜索树BST)
  1. 递归为root的val、left、right赋值
第四十三题(98验证二叉搜索树)
  1. Long.MIN_VALUE 与 Long.MAX_VALUE:定义为long类型的数
  2. 递归法:为每一个node的验证限制范围:min和max,在递归调用中改变上下限
  3. 中序遍历法,先访问到最左节点,再逐层向上向右访问
第四十四题(230二叉搜索树中第K小的元素)
  1. 思路同上中序遍历法,循环条件 while (root != null || !stack.isEmpty()) 表示此节点还没有遍历完(还在往下走)或栈内不为空(还有之前的祖先节点没处理)
第四十九题(236二叉树的最近公共祖先)
  1. 深度优先遍历:当左子树或右子树中有p/q或此时正在遍历的节点即为p或q时,dfs函数可以返回true;
  2. 当满足if (lson && rson || (root.val == p.val || root.val == q.val) && (lson || rson)) 条件时,即为找到了最近公共祖先

九、图论

第五十一题(200岛屿数量)
  1. 深度优先方法:依次遍历矩阵中的各个元素,并将与该元素能构成岛屿的节点的值设置为‘0’(注意这里是字符),对于每个节点上下左右依次进行判断是否要进行深度遍历
    时间复杂度:O(MN) 每个格子最多处理一次,邻居最多检查4MN,≤5MN
第五十二题(994腐烂的橘子)
  1. 多源广度优先遍历:使用队列存储腐烂的橘子,然后从每一个节点向四个方向延申,同时更新腐烂时间记录数组的值,这些操作使得每个节点最多被遍历一次
  2. 本题目使用C++编程练习,注意的语句:memset(dis, -1,sizeof(dis)); Q.emplace(i, j); Q.empty(); ~dis[tx][ty] (只有-1按位取反后的值为0)
第五十三题(207课程表)
  1. 思路转化:检查改题目的场景对应的图是否存在拓扑排序
  2. BFS方法:使用队列来保存入度初始为0或减至0的节点,每取出一个节点,就将以其为起点的边的另一头节点的 入度减一,减至0时加入队列,每取出一个节点并访问其相邻节点时,将答案数量增加一
  3. 本题目使用Java编程,注意的语句:queue.offer(i); queue.poll(); edges.add(newArrayList());
第五十四题(208实现 Trie (前缀树))

十、回溯

第五十五题(46全排列)
  1. 设置output的目的是:亦可用标记数组来表示哪些数已经放入结果数组中,若不使用,那么可以通过划分左右两侧的数据来实现,左侧为已经放入结果数组的,右侧为还没有的
  2. 如果first等于n,也就是n及以后的数还没有放入结果数组,即等价于所有数字已经全部放入结果数组,那么将该排列加入结果数组中
  3. 恢复现场的操作
第五十六题(78子集)
  1. 每个元素要么加入(1),要么不加入(0)集合,因此可以使用与其对应的(1 << n)个二进制数来表示集合中的存在情况
  2. 关键判断语句:if ((mask & (1<<i)) != 0):哪一位是1,则将其加入集合
  3. 最后一句为ans.add(new ArrayList < Integer > (t));,而不能是ans.add(t);?否则ans所有值都指向同一块t的内存地址,会存储最后一个子集的内容,即各个相同
第五十七题(17电话号码的字母组合)
  1. 建立按键字母Map后,回溯,直至每种情况下达到字母的最大长度
  2. 需要注意的语法:backtrack()函数中的new StringBuffer():支持append和delete,适合回溯,不同于String(字符串不可变);字符串取出某一个字母:digits.charAt(index)
第五十八题(39组合总和)
  1. 要想剪枝,需要排序:Arrays.sort(candidates);
第五十九题(22括号生成)
  1. 思路(合法的情况):当open括号个数比n小时,仍然可以加入open括号(即前括号),当close括号个数比open括号个数小时,可以加入close括号(即后括号)
  2. ans.add(cur.toString()); (其中cur为StringBuilder类型),这里不需要在add()方法中new,因为toString()方法就创建了一个新的String对象,不变地存储字符数组的内容
第六十题(79单词搜索)
  1. 各个数值作为第一个字符逐次遍历,而后对每一个的上下左右进行遍历,访问过的字符标记为’\0’,最后再赋值words[k]恢复现场(因为能执行到这里说明该元素值与work[k]是一致的)
  2. 将String转换为字符数组:char[] words = word.toCharArray();
第六十一题(131分割回文串)
第六十二题(51 N皇后)

十一、二分查找

第六十三题(35搜索插入位置)

1.找到序列中第一个≥target的值对应的位置

第六十四题(74搜索二维矩阵)
  1. 法一:两次二分查找;第一次首列上的二分查找,使用while(left < right)作为循环条件找到范围,第二次那一行上的二分查找,使用while(left <= right)作为循环条件找到是否有符合的值。
  2. 法二:一次二分查找,假想把各个行拼成一个序列,使用matrix[mid/n][mid%n]定位元素数值
第六十五题(34在排序数组中查找元素的第一个和最后一个位置)
  1. 需要使用一个lower变量,选择在寻找不小于还是大于的元素位置:if (nums[mid] > target || (lower && nums[mid] >= target))
  2. while (left <= right) 与 right = mid - 1、left = mid + 1 通常一起出现

判断条件的必要性:

在这里插入图片描述
第六十六题(33搜索旋转排序数组)
  1. if (nums[l] <= nums[mid])来判断左边的半个区间是否有序
  2. if (nums[l] <= target && target < nums[mid])来判断target是否在有序的那一侧范围内,如果不在则考虑另一侧
第六十七题(153寻找旋转排序数组中的最小值)
  1. 判断条件 while (l < r) 与 r = mid; 和 l = mid +1; 配对出现

如图,以high(最右侧的点的值)为基准,min至(high-1)的值都小于high的值,0至(min-1)的值都大于high的值

在这里插入图片描述
第六十八题(4寻找两个正序数组的中位数)

十二、栈

第六十九题(20有效的括号)

if (pairs.containsKey(chars[i])) 将括号映射为下面的哈希表,该语句用来判断目前是否正在处理后括号

在这里插入图片描述
第七十题(155最小栈)

使用一个辅助栈,用来记录每一次压入一个数据时当前的最小值是多少(因为后面元素的进出栈不影响前面的最小值)

在这里插入图片描述
第七十一题(394字符串解码)
  1. 这个题目思路比较清晰,但是编写起来需要注意的细节非常多,涉及到的数据类型很多
  2. 本题目中定义栈一定要使用LinkedList sub = new LinkedList< String >(); 因为Collections.reverse接收的是List类型的参数,不能声明为Deque
  3. 进而,这里要用addLast、removeLast()、peekLast()方法,
  4. 如果我把代码中的addLast()、removeLast()、peekLast()都换成push()、pop()、peek(),本应该输出aaabcbc的就会输出cbcbaaa,为什么呢?

两种转型语法

在这里插入图片描述
第七十二题(739每日温度)
  1. 使用单调栈,依次存入当前温度最高的那一天的下标(因为要计算的是 i - prevIndex);若新来的温度比栈顶下标对应的温度高,则弹出栈顶,因为距离它最近的比它温度高的那一天已经找到
第七十三题(84柱状图中最大的矩形)

十三、堆

第七十四题(215数组中的第K个最大元素)
  1. 堆排序方法:在一次 heapify 调用中,一个节点最多下沉:树的高度 次,也就是O(log n)
  2. 快速排序方法:挖坑法,随机选取一个数字,让其左边都比他小,右边都比他大,这个题目只需要不断递归寻找k所在的那一侧
第七十五题(347前K个高频元素)
  1. 使用最小堆,维持个数为k,利用记录的每个数字的频率,仅当遍历到的(数字,频率)对的频率大于堆顶时,弹出堆顶并压入;最终堆中保留的k个(数字,频率)对几位前K个高频元素
  2. for (Map.Entry<Integer, Integer> entry : occs.entrySet()),这是Java 的增强 for 循环(for-each),类似使用方法:for (int num: nums);因此可以理解Map.Entry<Integer, Integer>在这里表示一种数据类型
  3. 语法积累:queue.offer(new int[]{num, count});
第七十六题(295数据流的中位数)

十四、贪心算法

第七十七题(121买卖股票的最佳时机)

使用一个变量记录最小值,遍历一遍即可得到答案

在这里插入图片描述
第七十八题(55跳跃游戏)
  1. 使用rightmost变量在遍历过程中保存可到达的最右端位置
第七十九题(45跳跃游戏Ⅱ)

在每一个[0……end]范围中,遍历各个数字,得到下一步可到达的最远位置

在这里插入图片描述
第八十题(763划分字母区间)

记录每个字母出现的最后位置,然后在遍历过程中不断更新这个范围的end值,直到遍历变量i走到end的位置(说明该字母区间无需再延长)

在这里插入图片描述

总结

已涵盖了LeetCode Hot100中的大部分题目,后续会将没记录和没完成的题目继续补充完整~~

Read more

Flutter 三方库 matcher 的鸿蒙化适配指南 - 实现具备语义化断言与自定义匹配算法的测试契约框架、支持端侧质量验证的强力抽象实战

Flutter 三方库 matcher 的鸿蒙化适配指南 - 实现具备语义化断言与自定义匹配算法的测试契约框架、支持端侧质量验证的强力抽象实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 matcher 的鸿蒙化适配指南 - 实现具备语义化断言与自定义匹配算法的测试契约框架、支持端侧质量验证的强力抽象实战 前言 在进行 Flutter for OpenHarmony 开发时,当编写单元测试时,我们经常使用 expect(actual, matcher) 这种语法。你是否想过,如何让断言读起来像自然语言一样?或者,如何自定义一套专门针对鸿蒙原生组件状态的对比逻辑?matcher 是 Dart 官方维护的断言库扩展,它定义了测试中所有“匹配逻辑”的底层协议。本文将探讨如何在鸿蒙端构建极致、严谨的质量契约体系。 一、原直观解析 / 概念介绍 1.1 基础原理 该库建立在“谓词逻辑(Predicate Logic)”之上。它通过将复杂的 Object

By Ne0inhk

【学习记录】使用 John the Ripper 和 Hashcat破解 RAR、ZIP 与 7z 文件密码(Windows教程)

文章目录 * 📌 引言 * 📦 支持类型 * 🛠️ 所需工具下载地址(Windows 官方编译版) * 额外工具 * 🔐 一、破解RAR 压缩文件密码 * 步骤 1:获取RAR 文件的加密哈希值 * 步骤 2:将正确的哈希值复制到 `hash.txt` 文件 * 步骤 3:在 Hashcat 官方 wiki 查找 `-m` 哈希模式 ID * 步骤 4: 使用 Hashcat 破解哈希值 * 📁 二、破解ZIP 压缩文件密码 * 步骤 1:提取 ZIP 文件的加密哈希值 * 步骤 2:将正确的哈希值复制到 `hash.txt` 文件 * 步骤

By Ne0inhk
【大数据存储与管理】分布式文件系统HDFS:06 HDFS的数据读写过程

【大数据存储与管理】分布式文件系统HDFS:06 HDFS的数据读写过程

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈大数据技术原理与应用 ⌋ ⌋ ⌋专栏系统介绍大数据的相关知识,分为大数据基础篇、大数据存储与管理篇、大数据处理与分析篇、大数据应用篇。内容包含大数据概述、大数据处理架构Hadoop、分布式文件系统HDFS、分布式数据库HBase、NoSQL数据库、云数据库、MapReduce、Hadoop再探讨、数据仓库Hive、Spark、流计算、Flink、图计算、数据可视化,以及大数据在互联网领域、生物医学领域的应用和大数据的其他应用。 【GitCode】专栏资源保存在我的GitCode仓库:https://gitcode.com/Morse_Chen/BigData_principle_application。 文章目录 * 一、读数据的过程 * 二、写数据的过程 * 小结 在介绍 HDFS 的数据读写过程之前,需要简单介绍一下相关的类。FileSystem 是一个通用文件系统的抽象基类,可以被分布式文件系统继承,所有可能使用

By Ne0inhk
《算法闯关指南:优选算法--位运算》--36.两个整数之和,37.只出现一次的数字 ||

《算法闯关指南:优选算法--位运算》--36.两个整数之和,37.只出现一次的数字 ||

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 36. 两个整数之和 * 解法(位运算): * 算法思路: * C++算法代码: * 算法总结&&笔记展示: * 37.只出现一次的数字 || * 解法(比特位计数): * 算法思路: * C++算法代码: * 算法总结&&笔记展示: * 结尾: 前言: 聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法:理解“

By Ne0inhk