算法沉淀——分治算法(leetcode真题剖析)

在这里插入图片描述

算法沉淀——分治算法

  • 快排思想
    • 01.颜色分类
    • 02.排序数组
    • 03.数组中的第K个最大元素
    • 04.库存管理 III
  • 归并思想
    • 01.排序数组
    • 02.交易逆序对的总数
    • 03.计算右侧小于当前元素的个数
    • 04.翻转对

分治算法是一种解决问题的算法范式,其核心思想是将一个大问题分解成若干个小问题,递归地解决这些小问题,最后将它们的解合并起来得到原问题的解。分治算法的一般步骤包括分解(Divide)、解决(Conquer)、合并(Combine)。

具体来说,分治算法包含以下几个步骤:

  1. 分解(Divide): 将原问题分解成若干个规模较小、相互独立的子问题。这一步通常是问题规模的减小或者数据规模的缩小。
  2. 解决(Conquer): 递归地解决这些子问题。对于规模较小的子问题,可以直接求解。
  3. 合并(Combine): 将子问题的解合并起来,得到原问题的解。

分治算法通常适用于能够被划分成相互独立子问题的问题,并且这些子问题的结构和原问题一样。经典的分治算法有许多,如归并排序、快速排序、二分搜索等。

经典例子:归并排序

  1. 分解(Divide): 将待排序的数组分成两半。
  2. 解决(Conquer): 对每个子数组进行归并排序,递归地进行排序。
  3. 合并(Combine): 合并已排序的子数组,得到最终的排序结果。

分治算法的优点包括:

  • 模块化设计: 将问题分解成小问题,使得算法结构清晰,易于理解和实现。
  • 可并行性: 分治算法通常适用于并行计算,因为子问题可以独立地求解。
  • 适用范围广: 适用于一类问题,如排序、查找等。

快排思想

01.颜色分类

题目链接:https://leetcode.cn/problems/sort-colors/

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 012 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

示例 1:

输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]

示例 2:

输入:nums = [2,0,1]
输出:[0,1,2]

提示:

  • n == nums.length
  • 1 <= n <= 300
  • nums[i]012

思路

具体的思路可以分为以下三个部分:

  1. 红色部分(0): 通过交换,保证红色元素的右边界 left 的左侧都是红色元素。初始时,left 设置为-1。
  2. 白色部分(1): 遍历过程中,遇到白色元素(1)时,直接将指针 i 向右移动,不进行交换。白色元素已经排列在红色元素的右侧,所以不需要额外操作。
  3. 蓝色部分(2): 通过交换,保证蓝色元素的左边界 right 的右侧都是蓝色元素。初始时,right 设置为数组的长度。

整个过程在遍历指针 i 小于右边界 right 的情况下进行。当 iright 相遇时,排序完成。

代码

class Solution {
public:void sortColors(vector<int>& nums) {for(int i=0,left=-1,right=nums.size();i<right;){if(nums[i]==0) swap(nums[++left],nums[i++]);else if(nums[i]==1) i++;else swap(nums[i],nums[--right]);}}
};

02.排序数组

题目链接:https://leetcode.cn/problems/sort-an-array/

给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:

  • 1 <= nums.length <= 5 * 104
  • -5 * 104 <= nums[i] <= 5 * 104

思路

普通快排在这里是通过不了的,所以我们可以使用上面颜色分类的思想进行三路划分的优化

三路划分是对传统快速排序算法的一种改进,通过将数组划分为三个部分:小于、等于、大于基准值,从而在存在大量相同元素的情况下,提高了性能。

传统快速排序在处理有大量相同元素的数组时可能会导致不均匀的划分,使得递归树不平衡,进而影响性能。三路划分通过在划分过程中将数组分为小于、等于、大于基准值的三个部分,有效地解决了这一问题,具有以下优势:

  1. 减少重复元素的递归处理: 在存在大量相同元素的情况下,传统快速排序可能导致递归深度较大,而三路划分能够将相同元素聚集在一起,从而减少递归深度。
  2. 避免不必要的交换: 在传统快速排序中,可能会进行多次相同元素的交换,而三路划分通过将相同元素聚集在一起,避免了不必要的交换操作,提高了性能。
  3. 适用于含有大量重复元素的场景: 当数组中存在大量相同元素时,三路划分能够更好地利用重复元素的信息,提高排序效率。

三路划分的核心思想是通过一个循环,将数组划分为小于、等于、大于基准值的三个部分。这样,相同元素被聚集在等于基准值的部分,从而在递归过程中能够更高效地处理重复元素。这一优化使得算法在处理包含大量相同元素的数组时,性能更为稳定。

代码

class Solution {
public:int getRandom(vector<int>& nums,int left, int right){return nums[rand()%(right-left+1)+left];}void qsort(vector<int>& nums,int l, int r){if(l>=r) return;int key=getRandom(nums,l,r);int i=l,left=l-1,right=r+1;while(i<right){if(nums[i]<key) swap(nums[++left],nums[i++]);else if(nums[i]==key) i++;else swap(nums[--right],nums[i]);}qsort(nums,l,left);qsort(nums,right,r);}vector<int> sortArray(vector<int>& nums) {srand(time(NULL));qsort(nums,0,nums.size()-1);return nums;}
};

03.数组中的第K个最大元素

题目链接:https://leetcode.cn/problems/kth-largest-element-in-an-array/

给定整数数组 nums 和整数 k,请返回数组中第 **k** 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

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

示例 2:

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

提示:

  • 1 <= k <= nums.length <= 105
  • -104 <= nums[i] <= 104

思路

这里最常规的写法应该是使用堆排,但是这样达不到O(n)的时间复杂度,所以这里我们结合快排中的三路划分思想

代码

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {srand(time(NULL));  // 设置随机数种子return qsort(nums, 0, nums.size() - 1, k);}int qsort(vector<int>& nums, int l, int r, int k) {if (l == r) return nums[l];// 1. 随机选择基准元素int key = getRandom(nums, l, r);// 2. 根据基准元素将数组分为三块int left = l - 1, right = r + 1, i = l;while (i < right) {if (nums[i] < key) {swap(nums[++left], nums[i++]);} else if (nums[i] == key) {i++;} else {swap(nums[--right], nums[i]);}}// 3. 分情况讨论int c = r - right + 1, b = right - left - 1;if (c >= k) {// 第 k 大元素在右侧部分return qsort(nums, right, r, k);} else if (b + c >= k) {// 第 k 大元素等于基准元素return key;} else {// 第 k 大元素在左侧部分return qsort(nums, l, left, k - b - c);}}int getRandom(vector<int>& nums, int left, int right) {return nums[rand() % (right - left + 1) + left];}
};
  1. 计算左、右和基准三个部分的元素个数:
    • c 表示右侧部分元素的个数,即大于基准元素的个数。
    • b 表示基准元素左侧部分元素的个数,即等于基准元素的个数。
  2. 判断第 k 大元素的位置:
    • 如果右侧部分元素个数 c 大于等于 k,说明第 k 大元素在右侧部分。因此,递归地在右侧部分中继续寻找第 k 大元素。
    • 如果 b + c 大于等于 k,说明第 k 大元素等于基准元素。此时,基准元素即为所求的第 k 大元素,直接返回基准元素的值。
    • 如果以上两个条件都不满足,说明第 k 大元素在左侧部分。因此,递归地在左侧部分中继续寻找第 k 大元素,同时将 k 减去右侧和基准元素的个数。

这样的划分和递归过程保证了在不同情况下都能正确地找到第 k 大元素,从而完成整个算法。这是随机化快速排序在选择第 k 大元素时的一种处理策略,通过考虑基准元素左右两侧的元素个数,提高了算法在寻找第 k 大元素时的效率。

04.库存管理 III

题目链接:https://leetcode.cn/problems/zui-xiao-de-kge-shu-lcof/

仓库管理员以数组 stock 形式记录商品库存表,其中 stock[i] 表示对应商品库存余量。请返回库存余量最少的 cnt 个商品余量,返回 顺序不限

示例 1:

输入:stock = [2,5,7,4], cnt = 1
输出:[2]

示例 2:

输入:stock = [0,2,3,6], cnt = 2
输出:[0,2] 或 [2,0]

提示:

  • 0 <= cnt <= stock.length <= 10000 0 <= stock[i] <= 10000

思路

这一题和上一题的思路基本一致,同样我们使用快速选择的算法,可以使时间复杂度达到O(n),只不过需要简单做一些调整

代码

class Solution {
public:void qsort(vector<int>& nums, int l, int r, int k) {if (l >= r) return;// 随机选择基准元素int key = nums[rand() % (r - l + 1) + l];int left = l - 1, right = r + 1, i = l;// 划分过程while (i < right) {if (nums[i] < key) {swap(nums[++left], nums[i++]);} else if (nums[i] == key) {i++;} else {swap(nums[--right], nums[i]);}}int a = left - l + 1, b = right - left - 1;// 根据划分情况递归处理if (a > k) {// 第 k 小元素在左侧部分qsort(nums, l, left, k);} else if (a + b >= k) {// 第 k 小元素在基准元素右侧,且可能包含部分基准元素return;} else {// 第 k 小元素在右侧部分qsort(nums, right, r, k - a - b);}}vector<int> inventoryManagement(vector<int>& stock, int cnt) {srand(time(NULL));// 调用随机化快速排序qsort(stock, 0, stock.size() - 1, cnt);// 返回前 cnt 小的商品return {stock.begin(), stock.begin() + cnt};}
};

归并思想

01.排序数组

题目链接:https://leetcode.cn/problems/sort-an-array/

给你一个整数数组 nums,请你将该数组升序排列。

示例 1:

输入:nums = [5,2,3,1]
输出:[1,2,3,5]

示例 2:

输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]

提示:

  • 1 <= nums.length <= 5 * 104
  • -5 * 104 <= nums[i] <= 5 * 104

思路

要理解分治中的归并思想,首先我们从归并排序入手,这里我直接编写代码,想看更清晰的排序剖析,可以翻看博主之前关于八大排序的博客

代码

class Solution {vector<int> tmp;
public:vector<int> sortArray(vector<int>& nums) {tmp.resize(nums.size());mergeSort(nums, 0, nums.size() - 1);return nums;}void mergeSort(vector<int>& nums, int left, int right) {if (left >= right) return;// 计算中间位置int mid = (right + left) >> 1;// 递归对左右两部分进行归并排序mergeSort(nums, left, mid);mergeSort(nums, mid + 1, right);// 归并合并两个有序部分int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right)tmp[i++] = (nums[cur1] <= nums[cur2]) ? nums[cur1++] : nums[cur2++];while (cur1 <= mid) tmp[i++] = nums[cur1++];while (cur2 <= right) tmp[i++] = nums[cur2++];// 将归并后的结果拷贝回原数组for (int i = left; i <= right; ++i)nums[i] = tmp[i - left];}
};

02.交易逆序对的总数

题目链接:https://leetcode.cn/problems/shu-zu-zhong-de-ni-xu-dui-lcof/

在股票交易中,如果前一天的股价高于后一天的股价,则可以认为存在一个「交易逆序对」。请设计一个程序,输入一段时间内的股票交易记录 record,返回其中存在的「交易逆序对」总数。

示例 1:

输入:record = [9, 7, 5, 4, 6]
输出:8
解释:交易中的逆序对为 (9, 7), (9, 5), (9, 4), (9, 6), (7, 5), (7, 4), (7, 6), (5, 4)。 

限制:

0 <= record.length <= 50000

思路

这里我们使用归并的思想可以对数组边排序边进行逆序对的计算,我们在进行归并排序划分时,左边和右边都是相对有序的,我们在归并时,找到了左边相对右边大的那个数,就可以进行一次逆序对的组合,即此时左边被遍历的数及其之后的数都能和此时右边的数进行逆序匹配,此时我们累加逆序对的值,直到我们把整个数组归并完毕,逆序对的总数也就计算完毕了

代码

class Solution {int tmp[50000];
public:int reversePairs(vector<int>& record) {return mergeSort(record, 0, record.size() - 1);}int mergeSort(vector<int>& nums, int left, int right) {if (left >= right) return 0;int ret = 0;int mid = (left + right) >> 1;// 递归对左右两部分进行归并排序ret += mergeSort(nums, left, mid);ret += mergeSort(nums, mid + 1, right);// 归并合并两个有序部分,并统计逆序对个数int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right) {if (nums[cur1] <= nums[cur2]) {tmp[i++] = nums[cur1++];} else {ret += mid - cur1 + 1;  // 统计逆序对个数tmp[i++] = nums[cur2++];}}while (cur1 <= mid) tmp[i++] = nums[cur1++];while (cur2 <= right) tmp[i++] = nums[cur2++];// 将归并后的结果拷贝回原数组for (int i = left; i <= right; ++i)nums[i] = tmp[i - left];return ret;}
};

03.计算右侧小于当前元素的个数

题目链接:https://leetcode.cn/problems/count-of-smaller-numbers-after-self/

给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

示例 1:

输入:nums = [5,2,6,1]
输出:[2,1,1,0] 
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素

示例 2:

输入:nums = [-1]
输出:[0]

示例 3:

输入:nums = [-1,-1]
输出:[0,0]

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

思路

我们可以继续利用上面的逆序对思想,只不过我们需要使用额外的数组来记录相对下标。

代码

class Solution {vector<int> ret;vector<int> index;int tmp[500000];int tindex[500000];
public:vector<int> countSmaller(vector<int>& nums) {int n=nums.size();ret.resize(n);index.resize(n);for(int i=0;i<n;i++)  index[i]=i;mergeSort(nums,0,n-1);return ret;}void mergeSort(vector<int>& nums,int left,int right){if(left>=right) return;int mid=(left+right)>>1;mergeSort(nums,left,mid);mergeSort(nums,mid+1,right);int cur1=left,cur2=mid+1,i=0;while(cur1<=mid&&cur2<=right){if(nums[cur1]<=nums[cur2]){tmp[i]=nums[cur2];tindex[i++]=index[cur2++];}else{ret[index[cur1]]+=right-cur2+1;tmp[i]=nums[cur1];tindex[i++]=index[cur1++];}}while(cur1<=mid){tmp[i]=nums[cur1];tindex[i++]=index[cur1++];}while(cur2<=right){tmp[i]=nums[cur2];tindex[i++]=index[cur2++];}for(int j=left;j<=right;j++){nums[j]=tmp[j-left];index[j]=tindex[j-left];}}
};

04.翻转对

题目链接:https://leetcode.cn/problems/reverse-pairs/

给定一个数组 nums ,如果 i < jnums[i] > 2*nums[j] 我们就将 (i, j) 称作一个*重要翻转对*

你需要返回给定数组中的重要翻转对的数量。

示例 1:

输入: [1,3,2,3,1]
输出: 2

示例 2:

输入: [2,4,3,5,1]
输出: 3

注意:

  1. 给定数组的长度不会超过50000
  2. 输入数组中的所有数字都在32位整数的表示范围内。

思路

总体思路依旧是使用归并,我们在每次排序前,找到当前的左边某个数大于右边的两倍,即可一次性计算该数后面的翻转对个数,数组排序完成,即可计算全部的翻转对

代码

class Solution {int tmp[50000];
public:int reversePairs(vector<int>& nums) {return mergeSort(nums,0,nums.size()-1);}int mergeSort(vector<int>& nums,int left,int right){if(left>=right) return 0;int ret=0;int mid=(left+right)>>1;ret+=mergeSort(nums,left,mid);ret+=mergeSort(nums,mid+1,right);int cur1=left,cur2=mid+1,i=left;while(cur1<=mid){while(cur2<=right&&nums[cur2]>=nums[cur1]/2.0) cur2++;if(cur2>right) break;ret+=right-cur2+1;cur1++;}cur1=left,cur2=mid+1;while(cur1<=mid&&cur2<=right) tmp[i++]=nums[cur1]<=nums[cur2]?nums[cur2++]:nums[cur1++];while(cur1<=mid) tmp[i++]=nums[cur1++];while(cur2<=right) tmp[i++]=nums[cur2++];for(int j=left;j<=right;j++)nums[j]=tmp[j];return ret;}
};

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

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

相关文章

springboot182基于springboot的网上服装商城

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

2024-02-08 Unity 编辑器开发之编辑器拓展1 —— 自定义菜单栏

文章目录 1 特殊文件夹 Editor2 在 Unity 菜单栏中添加自定义页签3 在 Hierarchy 窗口中添加自定义页签4 在 Project 窗口中添加自定义页签5 在菜单栏的 Component 菜单添加脚本6 在 Inspector 为脚本右键添加菜单7 加入快捷键8 小结 1 特殊文件夹 Editor ​ Editor 文件夹是 …

GEE:CART(Classification and Regression Trees)回归教程(样本点、特征添加、训练、精度、参数优化)

作者:CSDN @ _养乐多_ 对于分类问题,这个输出通常是一个类别标签 ,而对于回归问题,输出通常是一个连续的数值。回归可以应用于多种场景,包括预测土壤PH值、土壤有机碳、土壤水分、碳密度、生物量、气温、海冰厚度、不透水面积百分比、植被覆盖度等。 本文将介绍在Google…

Linux network namespace 访问外网以及多命名空间通信(经典容器组网 veth pair + bridge 模式认知)

写在前面 整理K8s网络相关笔记博文内容涉及 Linux network namespace 访问外网方案 Demo实际上也就是 经典容器组网 veth pair bridge 模式理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼前的风景已…

docker本地目录挂载

小命令 1、查看容器详情 docker inspect 容器名称 还是以nginx为例&#xff0c;上篇文章我们制作了nginx静态目录的数据卷&#xff0c;此时查看nginx容器时会展示出来&#xff08;docker inspect nginx 展示信息太多&#xff0c;这里只截图数据卷挂载信息&#xff09;&#…

bugku 1

Flask_FileUpload 文件上传 先随便传个一句话木马 看看回显 果然不符合规定 而且发现改成图片什么的都不行 查看页面源代码&#xff0c;发现提示 那应该就要用python命令才行 试试ls 类型要改成图片 cat /flag 好像需要密码 bp爆破 根据提示&#xff0c;我们先抓包 爆破 …

matlab发送串口数据,并进行串口数据头的添加,我们来看下pwm解析后并通过串口输出的效果

uintt16位的话会在上面前面加上00&#xff0c;16位的话一定是两个字节&#xff0c;一共16位的数据 如果是unint8的话就不会&#xff0c; 注意这里给的是13&#xff0c;但是现实的00 0D&#xff0c;这是大小端的问题&#xff0c;在matlanb里设置&#xff0c;我们就默认用这个模式…

C++重新入门-C++ 函数

函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数&#xff0c;即主函数 main() &#xff0c;所有简单的程序都可以定义其他额外的函数。 您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的&#xff0c;但在逻辑上&#xff0c;划分通常…

鸿蒙开发理论之页面和自定义组件生命周期

1、自定义组件和页面的关系 页面&#xff1a;即应用的UI页面。可以由一个或者多个自定义组件组成&#xff0c;Entry装饰的自定义组件为页面的入口组件&#xff0c;即页面的根节点&#xff0c;一个页面有且仅能有一个Entry。只有被Entry装饰的组件才可以调用页面的生命周期。自…

基于轻量级模型YOLOX-Nano的菜品识别系统

工程Gitee地址&#xff1a; https://gitee.com/zhong-liangtang/ncnn-android-yolox-nano 一、YOLOX简介 YOLOX是一个在2021年被旷视科技公司提出的高性能且无锚框&#xff08;Anchor-free&#xff09;的检测器&#xff0c;在YOLO系列的基础上吸收近年来目标检测学术界的最新…

零基础学python之高级编程(3)---面向对象多态与封装(含有代码示例)

面向对象多态与封装 文章目录 面向对象多态与封装前言一、多态方法重写&#xff08;Overriding&#xff09;方法重载(Overloading)抽象基类和接口&#xff08;Abstract Base Classes and Interfaces&#xff09; 二、封装私有变量和私有方法属性装饰器(property) 和 getter和se…

AI绘画作品的展示和变现

AI绘画作品的展示和推广技巧 如何通过AI绘画打造独特的个人IP 4.1 AI绘画作品买卖 平台一&#xff1a;抖音 抖音平台有「抖音图文扶持计划」&#xff0c;还会不定期推出图文伙伴计划、图文热点来了等&#xff0c;大家起号的时候更容易 当你的每篇作品阅读量稳定在 1W 时&…

大话设计模式——1.模板方法模式(Template Method Pattern)

定义&#xff1a;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 例子&#xff1a;比较重大的考试往往有A、B两套试卷&#xff0c;其中一套出现问题可以立马更换另一套。 定义基…

2.12.。

1、选择芯片型号——STM32F051K8 2、开启调试功能 3、配置时钟 4、配置时钟树 5、工程管理

three.js 细一万倍教程 从入门到精通(一)

目录 一、three.js开发环境搭建 1.1、使用parcel搭建开发环境 1.2、使用three.js渲染第一个场景和物体 1.3、轨道控制器查看物体 二、three.js辅助设置 2.1、添加坐标轴辅助器 2.2、设置物体移动 2.3、物体的缩放与旋转 缩放 旋转 2.4、应用requestAnimationFrame …

c#cad 创建-文本(一)

运行环境 vs2022 c# cad2016 调试成功 一、代码说明 该代码是一个用于在AutoCAD中创建文本的命令。 首先&#xff0c;通过添加using语句引用了需要使用的Autodesk.AutoCAD命名空间。 然后&#xff0c;在命名空间CreateTextInCad下定义了一个名为CreateTextCommand的类&…

海里定理例题

1. lim ⁡ x − > 0 s i n ( 1 x ) \lim\limits_{x ->0}sin(\frac{1}{x}) x−>0lim​sin(x1​)的极限不存在 取数列f(x), x n 1 2 n Π − Π 2 x_n\frac{1}{2nΠ-\frac{Π}{2}} xn​2nΠ−2Π​1​和 y n 1 2 n Π Π 2 y_n\frac{1}{2nΠ\frac{Π}{2}} yn​2nΠ2…

Hive SQL编译成MapReduce任务的过程

一、 Hive 底层执行架构 1&#xff09; Hive简介 Hive是Facebook实现的一个开源的数据仓库工具。将结构化的数据文件映射为数据库表&#xff0c;并提供HQL查询功能&#xff0c;将HQL语句转化为MapReduce任务运行 2&#xff09; Hive本质&#xff1a;将 HQL 转化成 MapReduce 程…

Linux:搭建docker私有仓库(registry)

当我们内部需要存储镜像时候&#xff0c;官方提供了registry搭建好直接用&#xff0c;废话少说直接操作 1.下载安装docker 在 Linux 上安装 Docker Desktop |Docker 文档https://docs.docker.com/desktop/install/linux-install/安装 Docker 引擎 |Docker 文档https://docs.do…

手把手教你开发Python桌面应用-PyQt6图书管理系统-图书信息删除实现

锋哥原创的PyQt6图书管理系统视频教程&#xff1a; PyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~_哔哩哔哩_bilibiliPyQt6图书管理系统视频教程 Python桌面开发 Python入门级项目实战 (无废话版) 火爆连载更新中~共计24条视频&…