LeetCode 693. 交替位二进制数 / 2024. 考试的最大困扰度 / 1606. 找到处理最多请求的服务器
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 693. 交替位二进制数 / 2024. 考试的最大困扰度 / 1606. 找到处理最多请求的服务器相关的知识,希望对你有一定的参考价值。
693. 交替位二进制数
2022.3.28 每日一题
题目描述
给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。
示例 1:
输入:n = 5
输出:true
解释:5 的二进制表示是:101
示例 2:
输入:n = 7
输出:false
解释:7 的二进制表示是:111.
示例 3:
输入:n = 11
输出:false
解释:11 的二进制表示是:1011.
提示:
1 <= n <= 2^31 - 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-number-with-alternating-bits
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
class Solution
public boolean hasAlternatingBits(int n)
//直接用位运算的方法
//首先,n向右移动一位以后,与原来的数相与,就是都是1了
//然后怎么判断这个数都是1呢,就是 x 与 x + 1 相与,如果都是0,那么说明都是1
int t = n ^ (n >> 1);
//System.out.println(t);
return (t & (t + 1)) == 0;
2024. 考试的最大困扰度
2022.3.29 每日一题
题目描述
一位老师正在出一场由 n 道判断题构成的考试,每道题的答案为 true (用 ‘T’ 表示)或者 false (用 ‘F’ 表示)。老师想增加学生对自己做出答案的不确定性,方法是 最大化 有 连续相同 结果的题数。(也就是连续出现 true 或者连续出现 false)。
给你一个字符串 answerKey ,其中 answerKey[i] 是第 i 个问题的正确结果。除此以外,还给你一个整数 k ,表示你能进行以下操作的最多次数:
- 每次操作中,将问题的正确答案改为 ‘T’ 或者 ‘F’ (也就是将 answerKey[i] 改为 ‘T’ 或者 ‘F’ )。
请你返回在不超过 k 次操作的情况下,最大 连续 ‘T’ 或者 ‘F’ 的数目。
示例 1:
输入:answerKey = “TTFF”, k = 2
输出:4
解释:我们可以将两个 ‘F’ 都变为 ‘T’ ,得到 answerKey = “TTTT” 。
总共有四个连续的 ‘T’ 。
示例 2:
输入:answerKey = “TFFT”, k = 1
输出:3
解释:我们可以将最前面的 ‘T’ 换成 ‘F’ ,得到 answerKey = “FFFT” 。
或者,我们可以将第二个 ‘T’ 换成 ‘F’ ,得到 answerKey = “TFFF” 。
两种情况下,都有三个连续的 ‘F’ 。
示例 3:
输入:answerKey = “TTFTTFTT”, k = 1
输出:5
解释:我们可以将第一个 ‘F’ 换成 ‘T’ ,得到 answerKey = “TTTTTFTT” 。
或者我们可以将第二个 ‘F’ 换成 ‘T’ ,得到 answerKey = “TTFTTTTT” 。
两种情况下,都有五个连续的 ‘T’ 。
提示:
n == answerKey.length
1 <= n <= 5 * 10^4
answerKey[i] 要么是 ‘T’ ,要么是 ‘F’
1 <= k <= n
通过次数32,372提交次数56,404
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximize-the-confusion-of-an-exam
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
自己写了个滑动窗口,不知道当时怎么想的,非要一段一段连续的处理
然后就陷入了魔鬼细节中,改了好多次过的
class Solution
public int maxConsecutiveAnswers(String answerKey, int k)
//直接遍历统计个数就行了
//相当于一个滑动窗口吧,只不过这个窗口大小是根据这个字符串变化的
int count = 0;
char last = ' ';
List<Integer> list = new ArrayList<>();
//先统计个数
if(answerKey.length() <= k)
return answerKey.length();
for(char c : answerKey.toCharArray())
if(last != c)
last = c;
list.add(count);
count = 1;
else
count++;
list.add(count);
list.remove(0);
//System.out.println(list.size());
//System.out.println(list.get(0));
int left = 0;
int right = 1;
int l = list.size();
int temp = list.get(0);
int max = temp;
while(right < l)
int kk = k;
while(right < l && list.get(right) <= kk)
temp += list.get(right);
kk -= list.get(right);
temp += right + 1 < l ? list.get(right + 1) : 0;
right += 2;
//如果不能加整段,那么只能加一部分
if(right < l)
temp += kk;
//如果到了最后了,但是还有剩余,那么就在前面一段中加
else if(left > 0)
temp += list.get(left - 1) > kk ? kk : list.get(left - 1);
max = Math.max(max, temp);
if(right >= l)
break;
left += 1;
temp = list.get(left);
right = left + 1;
//System.out.println(max);
temp = list.get(l - 1);
for(int i = l - 2; i >= 0 && k > 0; i -= 2)
if(list.get(i) < k)
temp += list.get(i);
k -= list.get(i);
temp += i > 0 ? list.get(i - 1) : 0;
else
temp += k;
k = 0;
max = Math.max(max, temp);
return max;
后面发现一个一个字符处理更加简单方便
class Solution
//直接一个字符一个字符的滑动就可以了,如果另一个字符的个数大于k了,那么就把左端点移动
public int maxConsecutiveAnswers(String answerKey, int k)
return Math.max(maxConsecutiveChar(answerKey, k, 'T'), maxConsecutiveChar(answerKey, k, 'F'));
public int maxConsecutiveChar(String answerKey, int k, char ch)
int n = answerKey.length();
int ans = 0;
for (int left = 0, right = 0, sum = 0; right < n; right++)
sum += answerKey.charAt(right) != ch ? 1 : 0;
while (sum > k)
sum -= answerKey.charAt(left++) != ch ? 1 : 0;
ans = Math.max(ans, right - left + 1);
return ans;
1606. 找到处理最多请求的服务器
2022.3.30 每日一题
题目描述
你有 k 个服务器,编号为 0 到 k-1 ,它们可以同时处理多个请求组。每个服务器有无穷的计算能力但是 不能同时处理超过一个请求 。请求分配到服务器的规则如下:
- 第 i (序号从 0 开始)个请求到达。
- 如果所有服务器都已被占据,那么该请求被舍弃(完全不处理)。
- 如果第 (i % k) 个服务器空闲,那么对应服务器会处理该请求。
= 否则,将请求安排给下一个空闲的服务器(服务器构成一个环,必要的话可能从第 0 个服务器开始继续找下一个空闲的服务器)。比方说,如果第 i 个服务器在忙,那么会查看第 (i+1) 个服务器,第 (i+2) 个服务器等等。
给你一个 严格递增 的正整数数组 arrival ,表示第 i 个任务的到达时间,和另一个数组 load ,其中 load[i] 表示第 i 个请求的工作量(也就是服务器完成它所需要的时间)。你的任务是找到 最繁忙的服务器 。最繁忙定义为一个服务器处理的请求数是所有服务器里最多的。
请你返回包含所有 最繁忙服务器 序号的列表,你可以以任意顺序返回这个列表。
示例 1:
输入:k = 3, arrival = [1,2,3,4,5], load = [5,2,3,3,3]
输出:[1]
解释:
所有服务器一开始都是空闲的。
前 3 个请求分别由前 3 台服务器依次处理。
请求 3 进来的时候,服务器 0 被占据,所以它被安排到下一台空闲的服务器,也就是服务器 1 。
请求 4 进来的时候,由于所有服务器都被占据,该请求被舍弃。
服务器 0 和 2 分别都处理了一个请求,服务器 1 处理了两个请求。所以服务器 1 是最忙的服务器。
示例 2:
输入:k = 3, arrival = [1,2,3,4], load = [1,2,1,2]
输出:[0]
解释:
前 3 个请求分别被前 3 个服务器处理。
请求 3 进来,由于服务器 0 空闲,它被服务器 0 处理。
服务器 0 处理了两个请求,服务器 1 和 2 分别处理了一个请求。所以服务器 0 是最忙的服务器。
示例 3:
输入:k = 3, arrival = [1,2,3], load = [10,12,11]
输出:[0,1,2]
解释:每个服务器分别处理了一个请求,所以它们都是最忙的服务器。
示例 4:
输入:k = 3, arrival = [1,2,3,4,8,9,10], load = [5,2,10,3,1,2,2]
输出:[1]
示例 5:
输入:k = 1, arrival = [1], load = [1]
输出:[0]
提示:
1 <= k <= 10^5
1 <= arrival.length, load.length <= 10^5
arrival.length == load.length
1 <= arrival[i], load[i] <= 10^9
arrival 保证 严格递增 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-servers-that-handled-most-number-of-requests
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
和华为之前秋招的笔试题很类似,这里多了一个服务器的环,需要找环中下一个空闲服务器,而不是直接找最小编号的服务器处理,不算难
class Solution
public List<Integer> busiestServers(int k, int[] arrival, int[] load)
//有点类似华为的笔试题
//这个题有个什么问题呢,就是进来的请求需要按环找下一个空闲服务器处理
//想想这个该怎么办
//需要有一个集合放置空闲的服务器,并且这个集合还是按照大小排序的,那么就想到了TreeMap
//k个服务器处理的请求数目
int[] count = new int[k];
//放置空闲服务器,且按从小到大排序
TreeSet<Integer> free = new TreeSet<>();
//int[] 两个参数,一个服务器编号,一个空闲时间,按照空闲时间排序
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> (a[1] == b[1] ? a[0] - b[0] : a[1] - b[1]));
//先将所有的服务器放在set中
for(int i = 0; i < k; i++)
free.add(i);
int l = arrival.length;
for(int i = 0; i < l; i++)
int time = arrival[i];
//到达这个时间,如果有空闲的服务器,先放到set中
while(!pq.isEmpty() && pq.peek()[1] <= time)
int f = pq.poll()[0];
free.add(f);
int spend = load[i];
//需要第几个服务器
int need = i % k;
//找下一个空闲服务器
Integer realNeed = free.ceiling(need);
//如果找不到比它大的同时也没有比它小的
if(realNeed == null && free.isEmpty())
continue;
if(realNeed == null)
realNeed = free.first();
pq.offer(new int[]realNeed, time + spend);
count[realNeed]++;
free.remove(realNeed);
List<Integer> res = new ArrayList<>();
int max = count[0];
res.add(0);
for(int i = 1; i < k; i++)
if(count[i] > max)
res.clear();
max = count[i];
res.add(i);
else if(count[i] == max)
res.add(i);
return res;
python学习中
这里需要注意,busy作为一个优先队列,默认是按照第一个下标排序的
from sortedcontainers import SortedList
class Solution:
def busiestServers(self, k: int, arrival: List[int], load: List[int]) -> List[int]:
count = [0] * k
l = len(arrival)
busy = []
free = SortedList(range(k))
for i in range(l):
time = arrival[i]
spend = load[i]
while busy and busy[0][0] <= time:
free.add(busy[0][1])
heappop(busy)
if len(free) == 0:
continue
need = free.bisect_left(i % k)
if need == len(free):
need = 0
idx = free[need]
count[idx] += 1
heappush(busy, (time + spend, idx))
free.remove(idx)
maxf = max(count)
return [i for i in range(k) if count[i] == maxf]
以上是关于LeetCode 693. 交替位二进制数 / 2024. 考试的最大困扰度 / 1606. 找到处理最多请求的服务器的主要内容,如果未能解决你的问题,请参考以下文章