中国联通智网创新中心2021春招笔试题

中国联通智网创新中心2021春招笔试题

这个智网中心是2020年5月新建立的,之前没听过。然后这次报名参加了笔试,实际上这是第二次笔试,第一次题很难(对我来说)然后非常惨,考完之后人家将近两个礼拜没通知我,我就以为挂了,然后昨天中午突然打电话,HR小姐姐问我是否还想再参加一次。我:???她说第一次出的题很难。。。这次会简单点。我:???第一次听说这种事。
上次出的题目里面有vector,但是我之前没用过,所以直接傻眼了,我根本不知道用法是什么,就gg了。然后结束后我在牛客上做了一些这种题,知道用法了,然后相信这次起码在这个问题上不会再阻碍我了。然后证明这次确实简单了不少,最后题目1 AC 90% 题目2 100% 题目3 AC 100% 最后因为我把题目一点点敲下来时间不够想第一题了。

题目1(20分)

一个字符串中可能包含元音辅音字母和数字,请写出该字符串反转元音字母之后的结果,提示元音字母共十个a、e、i、o、u、A、E、I、O、U:

输入: “hello2WORld”
输出: “hOllo2WeRld”

输入: “abCd”
输出: “abCd”

第一道题因为我想的是要对单个字符进行操作,最后要组装成字符串而C++的那个流ostream类我忘记怎么用它将字符串数组转化为字符串,所以就用Java了,直接"+"链接岂不美滋滋。

public String changeLetters (String s) {
        // write code here
    	String ss="";
    	int len=s.length();
    	char a[]=new char[len];
    	for(int m=0;m<len;++m) a[m]=s.charAt(m);
    	int i=0,j=len-1;
    	int index[]=new int[len];//存放元音字母的下标
    	for(int n=0;n<len;++n) {
    		if(s.charAt(n)=='a'||s.charAt(n)=='A'||s.charAt(n)=='e'||s.charAt(n)=='E'||s.charAt(n)=='i'||s.charAt(n)=='I'||s.charAt(n)=='o'||s.charAt(n)=='O'||s.charAt(n)=='u'||s.charAt(n)=='U') {
    			index[n]=1;
    		}
    	}
    	while(i<j) {
    		while(index[i]!=1)++i;
    		while(index[j]!=1)--j;
    		if(i<j) {
    	    	char tmp=s.charAt(i);
    	    	a[i]=a[j];
    	    	a[j]=tmp;
    	    	++i;--j;
    	    }
    	}
    	for(int k=0;k<len;++k) ss=ss+a[k];
        return ss;
    }

下面是我本地IDE验证的主函数:

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String s="abCd";
		Solution so=new Solution();
		System.out.println(so.changeLetters(s));	
	}

本人比较菜,这道题只AC了90%。简单说下我的思路,有没有大神告诉我一下哪有缺陷:
对字符进行操作,就先保存到一个一维的字符数组中,同时构造一个同样大小的int型数组,是元音字母的位置就赋值为1,其他的不用管,时间复杂度O(N)。然后双指针从两端对int数组遍历(有点像快排但又有点区别),条件是(i<j,如果二者相等也不用交换)如果不为1就向中间靠拢,前面两个停下来的时候就是i、j指向的位置都是元音字母,然后交换数组中的对应位置即可。交换完了不要忘记将两个指针继续向中间靠拢一步,否则会无限交换下去。最后用空字符串 “”+char数组元素依次输出即可,总的时间复杂度O(N),空间复杂度O(N)。
可惜没想明白自己错在哪里了。。。望大家指教,拜托了🙏🙏🙏

题目2(20分)

某地有一块很长的空地,一部分作为停车位已出租,另一部分没有。如果新申请停车位,要求不能和现有的停车位相邻,如果现在用一个数组表示这块空地,其中包含数字0和1,没有作为停车位出租为0,作为停车位已出租为1,输入一个数字n表示新申请的停车位总量,判断是否成功

输入:[0,0,1,0,1,0,0,1],1
输出:true
说明:可以放在第一个位置,下标为0

输入:[1,0,1,0,0,0,1],2
输出:false
说明:只能放在下标为4的位置,只有一个,故返回false

bool ApplyParking(vector<int>& spots, int n) {
        // write code here
        int count=0;//记录符合题意得停车位的位置数
        int len=spots.size();
        int a[len]; 
        for(int i=0;i<len;++i){
			a[i]=spots[i];
		}
        for(int i=0;i<len;++i){
            if(i==0){
                if(a[0]==0&&a[1]==0) {
                	count++;
                	a[0]=1;
				}
            }else if(i==len-1){
                if(a[len-1]==0&&a[len-2]==0){
                	count++;
                	a[len-1]=1;
				} 
            }else{
                if(a[i-1]==0&&a[i]==0&&a[i+1]==0){
                	count++;
                	a[i]=1;
				} 
            }
        }
        if(count<n) return false;
        return true;
    }

主函数如下:

int main(){
	int a[]={1,0,1,0,0,0,1};
	vector<int > spots;
	for(int i=0;i<7;++i){
		spots.push_back(a[i]);
	}
	cout<<ApplyParking(spots, 2)<<endl;
	return 0;
} 

这个题比较简单就用C++写了
既然是要求不能和现有的停车位相邻,所以如果在数组两边的话就是与之相邻的左边(或右边)也为0,中间的话是相连的3个位置都得为0。用一个计数器count计算整个数组符合条件的个数位置,结果AC 90%,我傻了。不过最后还有两分钟结束时,我扫了一眼忽然发现自己的逻辑错了,极限改正,AC 100%,完美。一开始想错了,我用的vector数组spots直接判断,这个不能修改,导致像1,0,0,0,0,0,1这样的会判断成符合条件的有三个值(下标为2,3,4),实际上只有两个,下标为2和4.所以我赶紧又建立了一个同样大小的整型数组a将spors中的元素复制过去,然后每符合一个就将该位置改为1,在进行判断。比如上述例子中下标为2的位置0符合,然后将其修改为1,整个数组变为1,0,1,0,0,0,1,此时下标3在接下来的判断中就不会被判定为符合条件了。时间复杂度、空间复杂度都是O(N)。

题目3(30分)

回文字符串是一个正读和反读都一样的字符串,输入一个字符串,请判断在最多删减一个字母的规则下,该字符串能否变成一个回文字符串

输入: “mghm”
输出:true

输入: “o”
输出:true

public boolean validPalindrome (String s) {
        // write code here
    	int len=s.length();
    	if(len==1) return true;
    	int i=0,j=len-1,count=0;//count是记录不符合回文串的字符个数
    	int index1=-1,index2=-1;//记录第一次不符合回文串的下标,然后将剩下的字符在进行一次判断,如果还不符合,就报错
    	int flag1=1,flag2=1;//去掉左边的字符有可能不构成回文串,但是去掉右边的可能就会构成回文串,所以要判断两次 如"mmmhm"
    	while(i<j) {
    		if(s.charAt(i)!=s.charAt(j)) {
    			index1=i;//记录下下表
    			index2=j;//记录下下表
    			break;
    		}
    		++i;--j;   		
    	}
    	//System.out.println("index1="+index1+" index2="+index2);	
    	//for(int x=0;x<len;++x) System.out.print(s.charAt(x));
    	System.out.println();	
    	if(index1!=-1) {//不等于-1说明有不匹配的
    		char news[]=new char[len];
    		int y=0;
    		for(int k=0;k<len;++k) {
    			if(k!=index1) {
    				news[y]=s.charAt(k);//将去除不匹配字符的其余字符构成一个新数组
    				++y;
    			}
    		}
    		//for(int x=0;x<len;++x) System.out.print(news[x]);
        	//System.out.println();	
    		int m=0,n=len-2;
    		while(m<n) {
    			if(news[m]!=news[n]) flag1=0;//第二次不相符,直接返回错误
    			++m;--n;
    		}
    	}
    	if(index2!=-1) {//不等于-1说明有不匹配的
    		char news2[]=new char[len];
    		int y2=0;
    		for(int k=0;k<len;++k) {
    			if(k!=index2) {
    				news2[y2]=s.charAt(k);//将去除不匹配字符的其余字符构成一个新数组
    				++y2;
    			}
    		}
    		//for(int x=0;x<len;++x) System.out.print(news2[x]);
        	//System.out.println();	
    		int m2=0,n2=len-2;
    		while(m2<n2) {
    			if(news2[m2]!=news2[n2]) flag2=0;//第二次不相符,直接返回错误
    			++m2;--n2;
    		}
    	}
    	if(flag1==0&&flag2==0) return false;//只要有一个符合即可
    	return true;
    }

主函数如下:

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String s="mghm";
		Solution so=new Solution();
		System.out.println(so.validPalindrome(s));	
	}

这道题比较坎坷,简单说下思路:
既然是最多删去一个字符,还要进行字符串数组的比较,所以继续用java写好了。而且最多进行判断两次。同样利用双指针从两个方向开始向中间靠拢,如果有对应的字符不相等,记下此时两个指针所处的下标(这里第一次我只记录了index1,并没有记录index2,这样只AC了60%,原因是如果少考虑一种情况,去掉左边可能不能构成回文序列,但是去掉右边可能会构成回文序列,如"mmmhm"。此时i=1,j=3,如果去掉左边变成"mmhm",仍然不是回文序列,然后加上index2后判断右边,去掉h后就变为"mmmm",这就是一个回文序列了。)然后如果index1不为初始值-1就说明不是回文序列,需要去除掉该位置的字符,连接成一个新的字符串再判断第二次index2同理。第二次判断的时候如果还有不符合的就让对应的flag1、flag2改成0。如果最后有一个不为0就说明删除一个字符后是回文串。此时就AC了80%。然后我又看到了第一个while循环当找到不匹配的地方后没有跳出循环,加上break,完成。时间复杂度、空间复杂度都是O(N)。

还是太菜,之后再多刷刷题吧!

评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值