笔试编程题

两数之和(浦发)

笔试编程题_第1张图片
两数之和

我们保证输出结果必然存在且唯一,数组索引从1开始

只允许在solution方法内完成代码,不允许调用库函数,不允许在solution之外编写其他函数

思路

因为有序,双指针即可解决,注意溢出问题即可

code

//C代码
void solution(int* nums,int len_nums,int target,int*result,int len_result){
     
	int left = 0,right = len_nums - 1;
	while(left<right){
     
		if(nums[right]>target-nums[left])
			--right;
		else if(nums[left]<target-nums[right])
			++left;
		else{
     
			result[0]=left+1,result[1]=right+1;
			break;
		}
	}
}

回文数字判断(浦发)

笔试编程题_第2张图片

回文数

1表示true,0表示false

只允许在solution方法内完成代码,不允许调用库函数,不允许在solution之外编写其他函数

思路

数学解法:
1.计算n有多少位
2.得出10^(n-1)
3.分次取高位与低位,比较;相同则对n舍弃最高位与最低位,继续对比即可
辅助数组解法:
分割n的每一位(假设ncnt),存进数组arr;

for(int i = 0;i<cnt/2;++i)
	if(arr[i]!=arr[cnt-1-i])
		return 0;
return 1;

code

//C代码
int solution(int n){
     
	if(n<0)//排除负数
		return 0;
	int cnt = 1;
	int tmp_n = n;
	while(tmp_n/=10)//计算n的位数
		++cnt;
	int div = 1;
	for(int i = 1;i<cnt;++i)//得到10^(n-1),作为除数
		div*=10;
	while(n){
     
		if(n/div != n%10)//最高位与个位不同
			return 0;
		n%=10;//丢掉最高位
		n/=10;//丢掉个位
		div/=100;//更新除数
	}
	return 1;
}

数组乘积(浦发)

现有一串长度不固定的数组,数组内部为乱序排列,可能包含重复元素。先需要计算数组中每个元素粗自己外其他所有元素的乘积。

【样例输入1】[2,3,4,5,6]
【样例输出1】[360,240,180,144,120]
【解析1】
3x4x5x6=360,2x4x5x6=240,2x3x5x6=180,……
【样例输入2】[5,2,9,9,9,1,8,1,9,4]
【样例输出2】[419904,1049760,233280,……]
【解析2】与第一个例子类似,不再具体列举过程

只允许在solution方法内完成代码,不允许调用库函数,不允许在solution之外编写其他函数

思路

暴力解法1:
使用双重循环即可解决,遇到算过的数字复制乘积即可。
暴力解法2:
数组元素全乘起来,运用除法计算结果
乘积表解法3:
构建left,right乘积表即可解决

乘积表解法code

//C代码
void solution(int* arr, int arr_len, int* res,int res_len) {
     
	int dk = arr_len;
	while (dk /= 2) {
     //希尔排序
		for (int i = dk; i < arr_len; ++i) {
     
			if (arr[i - dk] > arr[i]) {
     
				int tmp = arr[i], j = i - dk;
				for (; j >= 0 && arr[j] > tmp; j-=dk)
					arr[j + dk] = arr[j];
				arr[j + dk] = tmp;
			}
		}
	}
	int* left = (int*)malloc(sizeof(int) * res_len);
	int* right = (int*)malloc(sizeof(int) * res_len);
	for (int i = 0; i < res_len; ++i) {
     //构建左乘积表
		if (arr[i] == arr[0]) {
     
			left[i] = 1;
			continue;
		}
		left[i] = left[i - 1] * arr[i - 1];
		int k = i + 1;
		while (arr[k] == arr[i])
			left[k++] = left[i];
		i = k - 1;
	}
	for (int i = res_len - 1; i >= 0; --i) {
     //构建右乘积表
		if (arr[i] == arr[res_len-1]) {
     
			right[i] = 1;
			continue;
		}
		right[i] = right[i + 1] * arr[i + 1];
		int k = i - 1;
		while (arr[k] == arr[i])
			right[k--] = right[i];
		i = k + 1;
	}
	for (int i = 0; i < res_len; ++i)
		res[i] = left[i] * right[i];
}

【若题目要求输出顺序,则该题应使用暴力解法】

魔法二进制(美团)

现有一个二进制序列,假如你会一个魔法,可以消除这个二进制序列中的任意相邻3个数字。现在请你计算此二进制序列被施加魔法后,二进制序列中0与1的最大数目差。(也可以不使用魔法,魔法只能使用一次)

输入描述:
第一行是一个正整数n表示二进制序列的长度
第二行是一个长度为n的二进制序列
输出描述:
输出一个正整数,表示施加魔法后二进制序列中0与1的最大数目差

eg.
输入
5
00001
输出
3

思路

暴力解法:
先统计01数目,然后遍历使用魔法,统计差值即可

code

#python代码
def BinTest(inp,n):
    if not n:#长度为0
        return 0
    zero_cnt,one_cnt = 0,0
    for x in inp:#统计01数目
        if x == 1:
            one_cnt += 1
        elif x == 0:
            zero_cnt += 1
    res = abs(zero_cnt-one_cnt)#不使用魔法的01数目差
    for i in range(0,n-2):
        tmp_zero,tmp_one = zero_cnt,one_cnt
        for j in range(i,i+3):#消除inp[i:1:i+2]
            if inp[j] == 1:
                tmp_one-=1
            else:
                tmp_zero-=1
        res = max(res,abs(tmp_one-tmp_zero))
    return res

n = int(input())
inp = list(map(int,input()))
print(BinTest(inp,n))

……美团题的其他一言难尽,1道忘记了,还有3道完全没想法。

你可能感兴趣的:(题海战术,c++)