第一题
找出花费时间最长的员工id号,如果花费时间相同,返回id号小那个。
当前完成工作时刻-上一个完成工作时刻 = 完成任务花费的时间,因此遍历一遍数组即可。时间复杂度O(n)
ac代码:
int hardestWorker(int n, vector<vector<int>>& logs) {
int m = logs.size();
int len = logs[0][1], id = logs[0][0];
for(int i = 1; i < m; i++){
int x = logs[i][1] - logs[i - 1][1];
if(len < x){
len = x;
id = logs[i][0];
}
if(len == x){
id = min(id, logs[i][0]);
}
}
return id;
}
第二题
累计异或值 ^ ans = 当前值,移项得ans = 当前值 ^ 累计异或值,遍历一遍即可,时间复杂度为O(n)
累计和的写法是模仿高精度加法来写的。
ac代码:
vector<int> findArray(vector<int>& pref) {
int n = pref.size();
vector<int> res(n);
res[0] = pref[0];
int t = res[0];
for(int i = 1; i < n; i++){
//当前值异或累计和t
res[i] = pref[i] ^ t;
t ^= res[i];
}
return res;
}
第三题
把题目意思提炼出来即为:有一个字符串s,给一个栈t,请你借助这个栈返回字典序最小的是s的排列。
方法是贪心, 因此思路比较跳跃。
由于栈顶是输出出来的第一个字符,当第一个字符的字典序越小, 整一个字符串的字典序就越小。
因此思路是:遍历s, 把当前元素push进栈, 比较栈顶和当前元素后面所有字符里字典序最小的字符。
- 如果栈顶小于当前元素后面所有字符,那么证明当前栈顶元素是最小的。应当优先输出。
- 如果栈顶大于当前元素后面所有字符,证明当前元素后面还有字符是字典序更小的存在,应该优先输出它们。
遍历完s后,如果stack里面还有字符,全部按顺序输出即可。
如果不加优化, 那么时间复杂度是O(n^2), 因为比较栈顶和当前元素后面所有字符是O(n)的。
因此可以先预处理一下,每一个以i为起点,n为结尾的序列最小的字符是什么。(这是一个简单的dp)
ac代码:
string robotWithString(string s) {
int n = s.size();
vector<char> f(n + 1);
初始化
f[n] = 'z' + 1;
求一下dp,每一个以i为起点,n为结尾的序列最小的字符是什么
for(int i = n - 1; i >= 0; i--) f[i] = min(f[i + 1], s[i]);
string ans;
stack<char> stk;
for(int i = 0; i < n; i++){
把当前元素放进栈里面
stk.push(s[i]);
比较栈顶元素和后面的字符哪一个比较小
while(stk.size() && stk.top() <= f[i + 1]) ans.push_back(stk.top()), stk.pop();
}
栈不空就全部输出出来
while(stk.size()){
ans.push_back(stk.top());
stk.pop();
}
return ans;
}
第四题
题型:数字三角形类型。在原有坐标上加上一个维度维护余数
状态定义:f[i][j][r] 在i, j的坐标里路径和模k余数是r
状态属性:cnt(状态之间相加)
状态转移:由于只能由左边和上边转移下来,因此状态转移方程还是类似的。
f[i][j][r] = f[i - 1][j][xxx] + f[i][j - 1][xxx]
问题就是这个xxx是什么了。可以推导一下:
所以
f[i][j][r] = f[i - 1][j][((r - gird[i][j] % k) + k) % k] + f[i][j - 1][((r - gird[i][j] % k) + k) % k]
这个+k模k的操作其实在数组下标–里面也用过。idx = ((idx - 1) + len) % len; 和这个类似
其实也可以这么写,既然r-grid[i][j] % k有可能小于0, 那么等式两边同时+grid[i][j] % k即可。
ac代码:
int numberOfPaths(vector<vector<int>>& grid, int k) {
int n = grid.size(), m = grid[0].size();
const int MOD = 1e9 + 7;
long long f[n + 1][m + 1][k];
memset(f, 0, sizeof f);
f[1][1][grid[0][0] % k] = 1;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
for(int r = 0; r < k; r++){
if(i == 1 && j == 1) continue;
f[i][j][r] = (f[i - 1][j][(r - grid[i - 1][j - 1] % k + k) % k] + f[i][j - 1][(r - grid[i - 1][j - 1] % k + k) % k]) % MOD;
}
}
}
return f[n][m][0];
}