2023中兴笔试复盘

本文探讨了快速排序算法在处理基本有序数据时的效率问题,并提供了实现代码。同时,介绍了Python函数参数、Java网络编程基础知识。还涉及软件开发模型、二分查找的时间复杂度计算以及辗转相除法求最大公约数的复杂度。最后,通过一道最小成本联通城市的问题,展示了使用并查集解决图论问题的思路和优化过程。
摘要由CSDN通过智能技术生成

选择加编程,选择题考的范围挺广的,编程题第一题有点难度,第二题还好,复盘一下遇到的有点卡顿的题目。

1.排序问题

快速排序最适合排完全无序的数据,如果基本有序的数据反而会耗时比较长,原因在于这种情况下一般拿第一个数做基准值的话,容易出现按基准值分为两半后左右不平衡,会让一边的递归完全失效,发挥不出快速排序的优势。
而且因为是基本有序的,容易出现对已经排好序的数组进行无效的递归排序的情况。
快排必须先从右边指针开始的原因: 我们的目标是小于基准值的全去左边,大于基准值的全去右边,因为最后有个交换操作,如果是右边先开始,最后停留位置是小于基准值的,如果是左边先开始,最后左右相遇的是大于基准值的,大于基准值的这个数要和基准值交换,破坏了顺序
快排代码:

#include <iostream>
using namespace std;

void quicksort(int left, int right, int nums[]){
	int key = left;//基准值下标
	int curl = left;//左指针
	int curr = right;//右指针
	while(curl < curr){//这个判断条件是让程序在第一次交换后继续进行
		//找右边第一个比基准值小的
		while(curl < curr && nums[curr] >= nums[key]){
			curr--;
		}
		//找左边第一个不符合要求,也就是比基准值大的,一样大的不用管,在之后的小数组里继续排序
		while(curl < curr && nums[curl] <= nums[key]){
			curl++;
		}
		if(curl < curr){//这时候curl前面的都是符合条件的, 3 2 4 ,curl指向4,我们需要交换3 和 2
			swap(nums[curl],nums[curr]);
		}else{
			swap(nums[key],nums[curl]);
			quicksort(left,curl-1,nums);
			quicksort(curl+1,right,nums);
		}
	}
}
int main(){
	int a[] = {10,2,4,5,1,8,7};
	quicksort(0,6,a);
	for(int num : a){
		cout << num << " ";
	}
}

2.python2函数参数格式

*arg 可变参数,参数不确定
arg = 9,直接确定好了参数的值,提供默认值
**arg 会把关键字参数转化为键值对,

3.java网络编程是在socket基础上的,而且是对ip、tcp协议都适用

4.软件开发模型:

  1. 边做边改模型
  2. 瀑布模型
  3. 快速原型模型
  4. 增量模型
  5. 螺旋模型
  6. 演化模型
  7. 喷泉模型
  8. 智能模型
  9. 混合模型
  10. RAD模型;

5.二分查找时间复杂度

二分查找是对半查找,查找次数x是总数n/2/2/2/2/2直到n为1的运算次数,所以2^x = n;时间复杂度x = 1og 2 n;

6.算法空间复杂度计算

在这里插入图片描述

7.辗转相除法求最大公约数的复杂度

辗转相除法思想:两个数m,n
1.得到m除以n的余数mod
2.将n作为新的被除数
2.将余数mod作为新的除数
……
重复以上过程,直至mod为0,此时的除数为最大公约数
代码实现:

#include <iostream>
#include <algorithm>
using namespace std;

int gcd(int a, int b){
	return b==0 ? a : gcd(b,a%b);
}
int main(){
	int res = gcd(346,897);
	cout << res;
}

注意这里核心代码的参数的位置,因为要做一个旧除数转为被除数这样一个操作,所以传参的时候位置要换一下。

8.编程题

类似题目:1135. 最低成本联通所有城市,https://leetcode.cn/problems/connecting-cities-with-minimum-cost/
1.按成本(边长)来排序
2.按照排好的顺序,依次构图,如果要添加的边的两个端点都已经添加过了,就不再重复添加了,否则则需要添加进去。每次添加的时候成本增加。

class UnionFindSet
{
private:
	vector<int>nums;
	int count;
public:
	UnionFindSet(int n){
		count = n;
		nums.resize(n+1);
		for(int i = 1; i <= n; i++){
			nums[i] = i;
		}
	}

    int find(int x){
		if(nums[x] == x){
			return x;
		}
		return find(nums[x]);
	}

	int merge(int node1, int node2){
		if(find(node1) == find(node2)){
			return false;
		}else{
			nums[max(node1,node2)] = min(node1,node2);
			count--;
			return true;	
		}
	}
	
	bool isable(){
		if(count == 2){
			return true;
		}else{
			return false;
		}
	}
};

class Solution {
public:
    int minimumCost(int n, vector<vector<int>>& connections) {
        sort(connections.begin(), connections.end(), [](const auto &a, const auto &b) {
            return a[2] < b[2];
        });
        UnionFindSet ufs(n);
		int res = 0;
        for(auto round : connections){
            if(ufs.merge(round[0], round[1])){
				res += round[2];
			}
        }
        return ufs.isable() ? -1 : res;
    }
};

但这个代码老是有一部分用例通过不了
在这里插入图片描述
我感觉的是问题出在联通集判断这

修改一下代码

class UFS{
private:
	vector<int>set;
	int count; //用来记录已经添加进去的节点数
	int sumcost;
public:
	//构造函数
	UFS(int n){
		count = n;
		sumcost = 0;
		set.resize(n+1);
	}
	//初始化集合
	void setcrt(int n){
		for(int i = 0; i <= n; i++){
			set[i] = i;
		}
	}
	//根据边关系梳理各节点之间关系
	void unioncrt(int a, int b, int cost){
		//第一种情况,两个点之前没有关系,统一用小的一个点做根
		if(set[a] != set[b]){
			int root = min(set[a],set[b]);//统一用这个去更新
			int key = max(set[a],set[b]);//将根为key的全部变为根为root
			for(int i = 0; i < set.size(); i++){
				if(set[i] == key){
					set[i] = root;
				}
			}
			count--;
			sumcost += cost;
		}
	}
	//是否可以全部联通
	bool isable(){
		if(count > 1){
			return false;
		}else{
			return true;
		}
	}
	//最小花费
	int getmincost(){
		return sumcost;
	}
};

class Solution {
public:
    int minimumCost(int n, vector<vector<int>>& connections) {
		sort(connections.begin(), connections.end(), [](const auto &a, const auto &b) {
            return a[2] < b[2];
        });
		UFS u(n);
		u.setcrt(n);
		for(int i = 0; i < connections.size(); i++){
			u.unioncrt(connections[i][0], connections[i][1], connections[i][2]);
		}
		if(u.isable()){
			return u.getmincost();
		}else{
			return -1;
		}
    }
};

勉强过了,但这个时间复杂度。。。
在这里插入图片描述
主要是每次的遍历修改根比较耗时,后面做一下优化吧。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值