编程面试_数组

数组面试题

    笔试和面试中,除了字符串,另一类出现频率极高的问题便是与数组相关的问题。解题思路:先一般考虑“万能的”暴力穷举(递归、回溯),如求n个数的全排列或八皇后(N皇后问题)。但因为穷举时间复杂度通常过高,所以需要考虑更好的方法。

如 分治法(通过分而治之,然后归并);

以及 空间换时间(如活用哈希表)。

此外,选择合适的 数据结构 可以显著提升效率,如寻找最小的k个数中,用 堆 代替 数组,也可借鉴快排思想,中枢分区方法。

再有,如果题目允许排序,则可以考虑 排序。

寻找和为定值的两个数中,先排序,然后用 前后两个指针 往中间扫描。

    而如果如果已经排好序了(如杨氏矩阵查找中),则想想有无必要二分,二分法。但是,如果题目不允许排序呢?这个时候,

我们可以考虑 不改变数列顺序的 贪心算法(如 最小生成树Prim、Kruskal 及 最短路dijkstra)

    或 动态规划(如 01背包问题,每一步都在决策)。最后,注意细节处理,不要忽略边界条件,如字符串转换成整数。

基础

int (*p)[10];// 首先(*p),p是一个指针,int [10],是一个包含10个int的数组,该指针p指向,这个数组// 是数组指针
int *p[10];  // 写成 int* p[10];比较合适,首先 [10]是一个包含 10个元素的数组,该元素类型为int*,即指向整形的指针// 是指针数组int a[10];// 整数数组
printf("%x\n",&a);// &a 是取一个数组的地址,是一个指针指向一个包含10个元素的数组,类型为 int (*p)[10];
printf("%x\n",a); // a 数组名,默认为数组首元素 a[0]的地址 和数组a的地址是同一个地址,该类型为指向一个整数的指针,即 int *p;
// 以上 &a 和 a 的值是一样的,是a[0]元素的存储地址,
// 但是含义不一样, &a指向了10个连续存储的整数, 而 a指向了一个 整数,即 a[0]// 类似的int (*p[])(int); // 函数指针数组。
// 首先(*p[]) 是一个指针数组,指向的类型为 int (int)是一个函数类型,输入一个int类型参数,输出一个int类型参数int (*p())[];    // 返回数组指针的函数。
// 首先 (*p()) 是一个返回指针类型的函数,该指针类型指向 int [] 即整形数组,即,p是一个返回整形数组指针的函数int *p()[]       // 字面上可以解释为返回指针数组的函数,不过函数是不能返回数组的。
// () 是一个函数, 返回类型为 int* [],是一个指针数组int *(*a())()    // 这是一个函数,它没有参数,它的返回值是一个函数指针,这个指针指向的函数,也没有参数,且返回值是int型的指针。

第一题 寻找集合中的最小的K个数

输入n个整数,输出其中最小的k个。

解法1 先排序再选择

    要求一个序列中最小的k个数,按照惯有的思维方式,则是先对这个序列从小到大排序,然后输出前面的最小的k个数。至于选取什么的排序方法,我想你可能会第一时间想到快速排序我们知道,快速排序平均所费时间为n*logn,然后再遍历序列中前k个元素输出即可。

因此,总的时间复杂度:O(n * log n)+O(k)=O(n * log n)。

解法2 选择排序思想

解法二

    咱们再进一步想想,题目没有要求最小的k个数有序,也没要求最后n-k个数有序。既然如此,就没有必要对所有元素进行排序。这时,咱们想到了用选择或交换排序,即:1、遍历n个数,把最先遍历到的k个数存入到大小为k的数组中,假设它们即是最小的k个数;2、对这k个数,利用选择或交换排序找到这k个元素中的最大值kmax(找最大值需要遍历这k个数,时间复杂度为O(k));3、继续遍历剩余n-k个数。假设每一次遍历到的新的元素的值为x,把x与kmax比较:如果x < kmax ,用x替换kmax,

并回到第二步重新找出k个元素的数组中最大元素kmax‘;如果x >= kmax,则继续遍历不更新数组,直到,k个数是此时最小的
         
每次遍历,更新或不更新数组的所用的时间为O(k)或O(0)。故整趟下来,时间复杂度为nO(k)=O(nk)。

解法3 利用最大堆 作为容器

    更好的办法是维护容量为k的最大堆,原理跟解法二的方法相似:1、用容量为k的最大堆存储最先遍历到的k个数,同样假设它们即是最小的k个数;2、堆中元素是有序的,令k1<k2<...<kmax(kmax设为最大堆中的最大元素)3、遍历剩余n-k个数。假设每一次遍历到的新的元素的值为x,把x与堆顶元素kmax比较:如果x < kmax,用x替换kmax,然后更新堆(用时logk);否则不更新堆。这样下来,总的时间复杂度:O(k+(n-k)*logk)=O(n*logk)。此方法得益于堆中进行查找和更新的时间复杂度均为:O(logk)(若使用解法二:在数组中找出最大元素,时间复杂度:O(k))。  

解法4 利用快排思想 得到大小数的 分区中枢

    int Cut(int a[], int low, int high){int temp = a[low];// 区间第一个元素 可以随机选择 在替换到low的位置while(low < high){while((low < higt)&&(a[high] > temp)) --high;// 从右边向左寻找比 temp小的元素 a[higt]a[low] = a[high];// 把比temp小的元素 放在 原来temp的位置(左边小的区域)while((low < high)&&(a[low] < temp))  ++low;// 从左边寻找比 temp大的元素a[low] 放在右边 high的位置a[high] = a[low];}a[low] = temp; // 临时变量 放在 中枢位置return low;    // 返回中枢位置}// 在数组a中选择k个最小的元素  块选  非递归调用void QuickSelest(int a[], int low, int high, int k){int index =  Cut(a, 0, n-1);// 首先得到一个中枢while(index != k-1){// 非递归调用if(index > k - 1) index = Cut(a, low, index -1);// 左半部分小的元素个数大于k 在左半部分找 中枢else              index = Cut(a, index+1, high);// 左半部分小的元素个数小于k 右半部分还有,在右半部分找 中枢}// 打印for(int i = 0; i<k; ++i) cout<<a[i];cout << endl;}// 而快排为   是递归调用void QuickSort(int a[], int low, int high){int index;if(low < high){index = Cut(a, low, high);//选取中枢位置QuickSort(a, low, index-1);//对左边快排QuickSort(a, index+1, high);//对右边快排}}// 二分查找   非递归版本int BinarySearch(int a[], int low, int high, int key){int mid;//中间元素while(low < high){int mid = low + ((high - low)>>1);//中间元素的 下标 在循环体内 不停的被改变if( key < a[mid] )     high = mid - 1;// 查找的元素小于中值  高区间移至 mid-1elae if(key > a[mid] ) low  = mid + 1;// 查找元素大于中值, 将低区间移至 mid+1else return mid;}return -1;//未找打 返回-1}// 二分查找   递归版本int BinarySearch(int a[], int low, int higt, int key){int mid = low + ((high - low)>>1);//中间元素的 下标if(low < high){if(key < a[mid])      return BinarySearch(a, low, mid-1, key);else if(key > a[mid]) return BinarySearch(a, mid+1, high, key);else return mid;}return -1;

}

第二题 寻找和为定值的两个数

    输入一个数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字。要求时间复杂度是O(N)。如果有多对数字的和等于输入的数字,输出任意一对即可。例如输入数组1、2、4、7、11、15和数字15。由于4+11=15,因此输出4和11。

思路:暴力搜索 时间复杂度 n^2
       其二,二分法(相当于用两个指针),从前后向中间搜索,看情况移动左右指针

代码如下

    // 二分(若无序,先排序后二分),时间复杂度总为O(N log N),空间复杂度为O(1);void findTwo2(int a[], int low, int high, int sum){//sort(a, a+high+1);   如果数组非有序的,那就事先排好序O(N log N)while(low < high){if(a[low] + a[high] > sum)      --high;//太大 right减少else if(a[low] + a[high] < sum) ++low; //太小 low增加else cout << a[low] << a[high] < endl;}cout << "Can't found" < endl;

}

总结

    不论原序列是有序还是无序,解决这类题有以下三种办法:1、二分(若无序,先排序后二分),时间复杂度总为O(N log N),空间复杂度为O(1);2、扫描一遍X-S[i] 映射到一个数组或构造hash表,时间复杂度为O(N),空间复杂度为O(N);3、两个指针两端扫描(若无序,先排序后扫描),时间复杂度最后为:有序O(N),无序O(N log N + N)=O(N log N),空间复杂度都为O(1)。所以,要想达到时间O(N),空间O(1)的目标,除非原数组是有序的(指针扫描法),不然,当数组无序的话,就只能先排序,后指针扫描法或二分(时间 O(Nlog N),空间O(1)),或映射或hash(时间O(N),空间O(N))。时间或空间,必须牺牲一个,达到平衡。综上,若是数组有序的情况下,优先考虑两个指针两端扫描法,以达到最佳的时O(N),空O(1)效应。否则,如果要排序的话,时间复杂度最快当然是只能达到O(N log N),空间O(1)则不在话下。

举一反三:

    输入:int[]nums int target 输出:符合要求的所有情况 给定一个int类型的数组,sum2、sum3、sum4分别输出2、3、4个元素的和为target的所有结果,不能重复,并且结果从小到大排序。【解法】: 三个题目均可以使用双指针的做法。首先对原始数组进行排序,排序的意义为:(1)保证最后结果的有序性;(2)从小到大的查找是否满足target,若小于他,则start指针往前走 ++start,若大于他,这end指针往回走 --end; 接着第一个指针从最小的元素开始,第二个指针从最大的元素开始,通过对和与target进行比较,判断start和end的走向。 sum2可以不用循环,只需要两个指针。同时sum2还可以有另一种解法,从左到右判断,采用一个集合保存判断过的结果,从集合中查找target-nums[i]是否存在;(n) sum3采用一层循环,start从循环处的下一个元素开始(n`2)sum4采用两层循环,第二层循环从第一层循环的i值开始,最内部start从第二层循环的下一个元素开始。(n`3) 

第三题 寻找和为定值的多个数

    题目描述

输入两个整数n和sum,从数列1,2,3…n 中随意取几个数,使其和等于sum,要求将其中所有的可能组合列出来。

01背包问题求解

    解法一注意到取n,和不取n个区别即可,考虑是否取第n个数的策略,可以转化为一个只和前n-1个数相关的问题。如果取第n个数,那么问题就转化为“取前n-1个数使得它们的和为sum-n”,对应的代码语句就是sumOfkNumber(sum - n, n - 1);如果不取第n个数,那么问题就转化为“取前n-1个数使得他们的和为sum”,对应的代码语句为sumOfkNumber(sum, n - 1)。0-1背包问题0-1背包问题是最基础的背包问题,其具体描述为:有N件物品和一个容量为V的背包。放入第i件物品耗费的费用是Ci,得到的价值是Wi。求解将哪些物品装入背包可使价值总和最大。简单分析下:这是最基础的背包问题,特点是每种物品仅有一件,可以选择放或不放。用子问题定义状态:即F[i, v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:F[i, v] = max{F[i-1, v], F[i-1, v-Ci ] + Wi}根据前面的分析,我们不难理解这个方程的意义:“将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只和前 i-1 件物品相关的问题。即:如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为 F[i-1, v ];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-Ci的背包中”,此时能获得的最大价值就是F[i-1, v-Ci]再加上通过放入第i件物品获得的价值Wi。list<int>list1;void SumOfkNumber(int sum, int n){// 递归出口if (n <= 0 || sum <= 0)return;// 输出找到的结果if (sum == n){// 反转listlist1.reverse();for (list<int>::iterator iter = list1.begin(); iter != list1.end(); iter++)cout << *iter << " + ";cout << n << endl;list1.reverse()//此处还需反转回来}list1.push_front(n); //放置进背包 当前占了n 前面剩余sum-n空间  典型的01背包问题SumOfkNumber(sum - n, n - 1);//“放”n,前n-1个数“填满”sum-nlist1.pop_front();// 取出来 不放进去 前面还剩余sum的空间SumOfkNumber(sum, n - 1); //不“放”n,n-1个数“填满”sum}

第四题 最大连续子数组和

    事实上,当我们令currSum为当前最大子数组的和,maxSum为最后要返回的最大子数组的和,当我们往后扫描时,对第j+1个元素有两种选择:要么放入前面找到的子数组,要么做为新子数组的第一个元素;如果currSum加上当前元素a[j]后不小于a[j],则令currSum加上a[j],否则currSum重新赋值,置为下一个元素,即currSum = a[j]。同时,当currSum > maxSum,则更新maxSum = currSum,否则保持原值,不更新。即:currSum = max(a[j], currSum + a[j])maxSum = max(maxSum, currSum)举个例子,当输入数组是1, -2, 3, 10, -4, 7, 2, -5,那么,currSum和maxSum相应的变化为:currSum: 0 1 -1 3 13 9 16 18 13maxSum : 0 1 1 3 13 13 16 18 18

参考代码如下:
int MaxSubArr(int* a, int num){
int currSum = 0;//初始化 当前和 为0
int maxSum = a[0];//初始化 第一个元素为 最大和
for(int j = 0; j < n; ++j ){
currSum = (currSum + a[j] > a[j] ) ? (currSum + a[j]) : a[j];
maxSum = maxSum > currSum ? maxSum : currSum;
}
return maxSum;
}

第五题 跳台阶问题

    一个台阶总共有n 级,如果一次可以跳1 级,也可以跳2 级。求总共有多少总跳法,并分析算法的时间复杂度。
解法一:首先考虑最简单的情况,函数递归调用求解。
    如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级;另外一种就是一次跳2级。现在我们再来讨论一般情况。我们把n级台阶时的跳法看成是n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2)。因此n级台阶时的不同跳法的总数f(n)=f(n-1)+f(n-2)。我们把上面的分析用一个公式总结如下:/  1                             n = 1f(n)=      2                             n = 2\  f(n-1) + f(n-2)               n > 2原来上述问题就是我们平常所熟知的Fibonacci数列问题。

可编写代码,如下:

    longn long Fibonacci(unsigned int n){int result[] = [0, 1, 2];if (n <= 2)  return result[n];else return Fibonacci(n-1) + Fibonacci(n-2);}
那么,如果一个人上台阶可以一次上1个,2个,或者3个呢?这个时候,公式是这样写的:
            / 1                                      n = 1f(n)=     2                                      n = 24                                      n = 3       //111, 12, 21, 3\ f(n-1) + f(n-2) + f(n-3)               n > 3

可编写代码,如下:

    longn long F(unsigned int n){int result[] = [0, 1, 2, 4];if (n <= 3)  return result[n];else return F(n-1) + F(n-2) + F(n-3);}

解法二,循环递推公式求解

解法一用的递归的方法有许多重复计算的工作,事实上,我们可以从后往前推,一步步利用之前计算的结果递推。+
初始化时,dp[0]=dp[1]=1,
然后循环递推计算即可:dp[n] = dp[n-1] + dp[n-2],当前解 等于前两次的和

参考代码如下:

    // 1,1,2,3,5,8,13,21..int ClimbStairs(int n){// n级台阶,可以一次调1个台阶和2个台阶两种选择,有多少种跳发int dp[3] = {1, 1};// 保存当前值 上一次值 上上次值的数组if(n <=1) return 1;else {for(int i = 2; i <= n; ++i){d[2] = d[1] + d[0];d[0] = d[1];d[1] = d[2];// 更新数组的值}}}
换硬币问题
    // 想兑换100元钱,有1,2,5,10四种钱,问总共有多少兑换方法。 递推公式 arr[j] += arr[j - dimes[i]];const int N = 100;int dimes[] = { 1, 2, 5, 10 };int arr[N + 1] = { 1 };//存放每一个总钱数可以的兑换次数int coinExchange(int n)   //非递归实现       {for (int i = 0; i < sizeof(dimes) / sizeof(int); ++i)//对于每一个面值{for (int j = dimes[i]; j <= n; ++j)// 遍历总钱数j ~ n{arr[j] = arr[j] + arr[j - dimes[i]];//分为两种情况,//总钱数j,如果没有换当前硬币i,那么是多少?arr[j]//加上,如果换了当前硬币dimes[i],总值减少为 j-dimes[i],此时又是多少种兑换方法?arr[j-dimes[i]]}}return arr[n];}

奇偶调序

    输入一个整数数组,调整数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。

方法1 利用快排思想 奇偶数分类下标 头指针,向右移动 尾指针,向左移动

    借鉴partition 分治 的实现一,我们可以考虑维护两个指针,一个指针指向数组的第一个数字,我们称之为头指针,向右移动;一个指针指向最后一个数字,称之为尾指针,向左移动。这样,两个指针分别从数组的头部和尾部向数组的中间移动,如果第一个指针指向的数字是偶数而第二个指针指向的数字是奇数,我们就交换这两个数字。因为按照题目要求,最终是为了让奇数排在数组的前面,偶数排在数组的后面,所以头指针理应指向的就是奇数,尾指针理应指向的就是偶数,

故当头指针指向的是偶数且尾指针指向的是奇数时,我们就当立即交换它们所指向的数字。

代码实现:

    // 判断是否为奇数bool isOddNumber(int n){return n & 1 == 1; // 奇数 的最后一个二进制位为1}// void OddEvenChange(int *a, int num){if(a == NULL|| num == 0) return;// 空指针 以及长度为0 直接返回int* low  = a;           // 头指针int* high = a + num - 1; // 尾指针while(low < high){if(!isOddNumber(*high) --high;//如果 high指针指向的是偶数,正常,向前移 减小else if(isOddNumber(*low) ++low;//如果 low指针指向的是奇数,正常,向后移 加大else //否则都不正常,交换//swap是STL库函数,声明为void swap(int& a, int& b);swap(*pBegin, *pEnd);}}

本方法通过头尾两个指针往中间扫描,一次遍历完成所有奇数偶数的重新排列,时间复杂度为O(n)。

荷兰旗 三色球 问题  三类的分配问题

    现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右,依次是一些红球(类1)、一些白球(类2)、一些蓝球(类3)。通过前面的分析得知,这个问题类似快排中partition过程,只是需要用到三个指针:一个前指针begin(指向类1),一个中指针current(指向类2),一个后指针end(指向类3),current指针遍历整个数组序列,当:current指针所指元素为 类1 时,与begin指针所指的元素交换,而后current++,begin++ ;current指针所指元素为 类2 时,不做任何交换(即球不动), 而后current++ ;current指针所指元素为 类3 时,与end指针所指的元素交换,  而后,current指针不动(end指向的元素可能为类1 ),end-- 。

参考代码如下:

    while( current<=end )        {             if( array[current] ==0 )             {                 swap(array[current],array[begin]);                  current++;                  begin++;            }             else if( array[current] == 1 )            {                 current++;            }   else //When array[current] =2   {               swap(array[current],array[end]);                end--;            }      }

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

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

相关文章

第80步 时间序列建模实战:GRNN回归建模

基于WIN10的64位系统演示 一、写在前面 这一期&#xff0c;我们使用Matlab进行GRNN模型的构建。 使用的数据如下&#xff1a; 采用《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrom…

使用SDKMAN在Linux系统上安装JDK

本文使用的Linux发行版为Rocky Linux 9.2&#xff0c;可以当做CentOS的平替产品。 SDKMAN是一个sdk包管理工具&#xff0c;通过自带的命令可以快速切换软件环境&#xff0c; 官网地址&#xff1a;https://sdkman.io/。 1、安装sdkman&#xff1a; # curl -s "https://ge…

SpringBoot整合RocketMQ笔记

SpringBoot版本为2.3.12.Release RocketMQ对比kafka 学习链接 https://zhuanlan.zhihu.com/p/335216381 代码实战 https://www.cnblogs.com/RedOrange/p/17401238.html Centos安装rocketmq https://blog.csdn.net/chuige2013/article/details/123783612 RocketMQ详细配置与…

mfc 动态加载dll库,Mat转CImage,读ini配置文件,鼠标操作,在edit控件上画框,调试信息打印

动态加载dll库 h文件中添加 #include "mydll.h" #ifdef UNICODE //区分字符集 #define LoadLibrary LoadLibraryW #else #define LoadLibrary LoadLibraryA #endif // !UNICODEtypedef double(*mydllPtr)(int, int);类内添加&#xff1a; mydllPtr m_mydll; cpp…

centos rpm方式安装jenkins

rpm方式按照jenkins 1. jenkins rpm下载 [rootlocalhost software]# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.361.4-1.1.noarch.rpm该版本要使用jdk11 2. 创建jenkins安装需要的文件夹 [rootlocalhost software]# mkdir -p /var/cache…

【C语言深入理解指针(2)】

1. 数组名的理解 在上⼀个博客我们在使⽤指针访问数组的内容时&#xff0c;有这样的代码&#xff1a; int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0];这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址&#xff0c;但是其实数组名本来就是地址&#x…

C++ - 开散列的拉链法(哈希桶) 介绍 和 实现

前言 之前我们介绍了&#xff0c;闭散列 的 开放地址法实现的 哈希表&#xff1a;C - 开放地址法的哈希介绍 - 哈希表的仿函数例子_chihiro1122的博客-CSDN博客 但是 闭散列 的 开放地址法 虽然是哈希表实现的一种&#xff0c;但是这种方式实现的哈希表&#xff0c;有一个很大的…

【操作系统】了解Linux操作系统中PCB进程管理模块与进程PID

本篇要分享的内容是有关于操作系统中进程的内容。 目录 1.进程的简单理解 2.了解task_struct&#xff08;进程控制模块&#xff09;内容分类 3.task_struct&#xff08;进程控制模块&#xff09;中的PID 4.调用查看PID的函数 1.进程的简单理解 首先我们需要理解的是什么是…

C++指针的使用

文章目录 1.C指针1.1 定义指针1.2 使用指针 2.空指针和野指针2.1 空指针2.2 野指针 3.指针所占空间4.使用const修饰指针4.1 const修饰指针4.2 const修饰常量4.3 const 既修饰指针也修饰常量 5.指针操作数组6.指针做函数参数7.使用指针知识实现冒泡排序 1.C指针 指针其实就是一…

【python数据建模】Numpy库

数组 创建 import numpy as np # np.array() 生成元素同类型的数组 a1np.array([1,2,3,4]) # 整型 a2np.array([1.0,2,3,4]) # 浮点型 a3np.array([1,2,3,4],dtypefloat) a4np.array([1,2,3,4]) # 字符串# np.astype() 数值类型转换 aa4.astype(int) print(a.dtype)# np.aran…

SpringBoot整合数据库连接

JDBC 1、数据库驱动 JDBC&#xff08;Java DataBase Connectivity&#xff09;&#xff0c;即Java数据库连接。简而言之&#xff0c;就是通过Java语言来操作数据库。 JDBC是sun公司提供一套用于数据库操作的接口. java程序员只需要面向这套接口编程即可。不同的数据库厂商&…

【C++】特殊类设计

文章目录 一、请设计一个类&#xff0c;只能在堆上创建对象二、请设计一个类&#xff0c;只能在栈上创建对象三、请设计一个类&#xff0c;不能被拷贝四、请设计一个类&#xff0c;不能被继承 一、请设计一个类&#xff0c;只能在堆上创建对象 实现方式 将类的构造函数私有&a…

Ubuntu配置深度学习环境(TensorFlow和pyTorch)

文章目录 一、CUDA安装1.1 安装显卡驱动1.2 CUDA安装1.3 安装cuDNN 二、Anaconda安装三、安装TensorFlow和pyTorch3.1 安装pyTorch3.2 安装TensorFlow2 四、安装pyCharm4.1 pyCharm的安装4.2 关联anaconda的Python解释器 五、VScode配置anaconda的Python虚拟环境 前言&#xff…

本地部署 川虎 Chat

本地部署 川虎 Chat 1. 川虎 Chat 项目概述2. Github 地址3. 部署 川虎 Chat4. 配置 config.json5. 启动 川虎 Chat 1. 川虎 Chat 项目概述 为ChatGPT等多种LLM提供了一个轻快好用的Web图形界面和众多附加功能。 支持 GPT-4 基于文件问答 LLM本地部署 联网搜索 Agent 助理…

计算机竞赛 深度学习手势识别 - yolo python opencv cnn 机器视觉

文章目录 0 前言1 课题背景2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存 5 模型训练5.1 修…

数据结构:复杂度分析

目录 1 算法效率评估 1.1 实际测试 1.2 理论估算 2 迭代与递归 2.1 迭代 1. for 循环 2. while 循环 3. 嵌套循环 2.2 递归 1. 调用栈 2. 尾递归 3. 递归树 2.3 两者对比 3 时间复杂度 3.1 统计时间增长趋势 3.2 函数渐近上界…

MySQL学习笔记26

MySQL主从复制的搭建&#xff08;AB复制&#xff09; 传统AB复制架构&#xff08;M-S)&#xff1a; 说明&#xff1a;在配置MySQL主从架构时&#xff0c;必须保证数据库的版本高度一致&#xff0c;统一版本为5.7.31 环境规划&#xff1a; 编号主机名称主机IP地址角色信息1ma…

460. LFU 缓存

请你为 最不经常使用&#xff08;LFU&#xff09;缓存算法设计并实现数据结构。 实现 LFUCache 类&#xff1a; LFUCache(int capacity) - 用数据结构的容量 capacity 初始化对象int get(int key) - 如果键 key 存在于缓存中&#xff0c;则获取键的值&#xff0c;否则返回 -1…

盛最多水的容器 接雨水【基础算法精讲 02】

盛雨水最多的容器 链接 : 11 盛最多水的容器 思路 : 双指针 &#xff1a; 1.对于两条确定的边界&#xff0c;l和r,取中间的线m与r组成容器&#xff0c;如果m的高度>l的高度&#xff0c;那么整个容器的长度会减小&#xff0c;如果低于l的高度&#xff0c;那么不仅高度可…