腾讯笔试 后台开发(4AC,最后一题不会,带代码)

1、链表分组
第一题直接模拟即可,不贴代码了,
超时的估计是在存链表的时候每次都遍历到链表结尾再存,这样肯定超时。
其实就是考了一个翻转链表的套路,每次存的时候存链表尾,然后在最后输出的时候每个依次翻转一次链表就完事了。

2、魔法球
贪心排序
直接对魔法球进行从大到小贪心排序,从头到尾消除即可。
超时的话估计是每消除一个魔法球,就遍历剩余的球加分,这样n平方复杂度肯定超时。

其实思路就是用一个变量保存前面消除魔法球的增量,每消除一个魔方球时,就把当前魔法球和增量都加入ans,然后增量在增加就好了。
坑点:每次加的时候记得取余
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{

	int T;
	cin >> T;
	int mod = 1000000007;
	for (int i = 0; i < T; i++) {
		int n;
		cin >> n;
		
		vector<int> vec;
		for (int j = 0; j < n; j++) {
			int tmp;
			cin >> tmp;
			vec.push_back(tmp);
		}
		sort(vec.begin(), vec.end(), greater<int>());
		long long ans = 0;
		long long sum = 0;
		for (int k = 0; k < n; k++) {
			ans += (sum + vec[k]);
			ans %= mod;
			sum += (sum + vec[k]);
			sum %= mod;
		}
		cout << ans << endl;
	}
}

3、刻舟求剑
很直观的思路,奇数和偶数分组排序,奇数遍历一次,偶数遍历一次,
遍历的时候,双指针首尾,首尾相加小于载重,船+1,left++, right--,大于载重,right--,船+1,因为这个最重的人只能一个人坐船了。
我还用了二分,看别人解法应该不用二分,上述的思路直接得出最小值了,我还是贴我的二分代码出来了,没超时
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;


bool findNum(vector<int>& vec1, vector<int>& vec2, int num, int w) {
	int count = 0;
	int left = 0, right = vec1.size() - 1;
	while (left <= right) {
		if (left == right) {
			count++;
			break;
		}
		else {
			int v = vec1[left] + vec1[right];
			if (v <= w) {
				count++;
				left++;
				right--;
			}
			else if (v > w) {
				count++;
				right--;
			}
		}
	}

	if (count > num) {
		return false;
	}

	left = 0, right = vec2.size() - 1;
	while (left <= right) {
		if (left == right) {
			count++;
			break;
		}
		else {
			int v = vec2[left] + vec2[right];
			if (v <= w) {
				count++;
				left++;
				right--;
			}
			else if (v > w) {
				count++;
				right--;
			}
		}
	}
	return count <= num;
}

int main() {

	int T;
	cin >> T;
	while (T > 0) {
		T--;
		int n, w;
		cin >> n >> w;
		vector<int> vec1;
		vector<int> vec2;
		for (int i = 0; i < n; i++) {
			int tmp;
			cin >> tmp;
			if (tmp % 2) {
				vec1.emplace_back(tmp);
			}
			else {
				vec2.emplace_back(tmp);
			}
		}
		sort(vec1.begin(), vec1.end());
		sort(vec2.begin(), vec2.end());
		int left = 1, right = n, pos = -1;
		while (left <= right) {
			int mid = left + (right - left) / 2;
			if (findNum(vec1, vec2, mid, w)) {
				pos = mid;
				right = mid - 1;
			}
			else {
				left = mid + 1;
			}
		}
		cout << pos << endl;
	}
	return 0;
}

4、求字符串
维护一个严格单调递减栈即可,但维护弹栈的时候需要考虑后面的字符还够不够选
#include <iostream>
#include<stack>
#include<string>
using namespace std;

int main()
{
 int n, k;
 cin >> n >> k;
 string s;
 cin >> s;
 stack<char> stk;
 for (int i = 0; i < n; i++) {
  //维护一个严格单调递减栈
  //如果当前字符比栈顶字符大,普通单调递减栈就是直接弹出,直接栈为空,或者遇到栈顶字符比当前字符大
  //但是在该题中需要考虑,如果把栈的字符弹出了,后续字符还够不够选择,所以需要判断一下,也就是n - i > k的作用
  while (!stk.empty() && stk.top() < s[i] && n - i > k) {
   stk.pop();
   //弹出一次,可选字符k++
   k++;
  }
  //如果k小于等于0,不能加字符了
  if (k <= 0) {
   continue;
  }
  //当前字符小于或等于栈顶字符,或者栈空
  stk.push(s[i]);
  k--;
 }
 //逆序输出即可
 string ans = "";
 while (!stk.empty()) {
  ans += stk.top();
  stk.pop();
 }
 reverse(ans.begin(), ans.end());
 cout << ans << endl;
}
5、涂方块
完全不会,暴力也不会,求思路,私聊回复都行。

#腾讯笔试##笔经##腾讯#
全部评论
第五题暴力枚举起始点,最后一个dp,dp[i][j][k](k=0或1)表示区间[i,j]全部相同时,都等于a[i]或者a[j]的最小代价,转移方程自己推吧,一共四个转移方程
点赞 回复
分享
发布于 2021-08-23 00:15
兄弟,字节考虑下吗?我们是字节跳动中国区风控团队,负责字节跳动中国区全系产品(包括抖音、头条等)的业务风控,岗位涵盖算法、大数据、后端、前端,多投递一个岗位多一次机会哦~直接私聊我呀~
点赞 回复
分享
发布于 2021-08-23 12:45
滴滴
校招火热招聘中
官网直投
我对比了4,5题,然后毅然选择第五题,结果没做出来。就在交卷前5分钟,思路就来了。 思路:求平均,选出离平均值最近的元素值a,然后求每个元素离平均值的差值(带符号),然后从头到尾遍历,寻找都是差值都是大于0的且连续的元素,他们这一堆所需消耗的就是(最大值-a) ,然后小于0的同样的思路。
点赞 回复
分享
发布于 2021-08-23 21:11

相关推荐

3 14 评论
分享
牛客网
牛客企业服务