LeetCode342. 4的幂 / 第243场周赛
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode342. 4的幂 / 第243场周赛相关的知识,希望对你有一定的参考价值。
342. 4的幂
2021.5.31 每日一题,很开心这个月又收货徽章了!
题目描述
给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true ;否则,返回 false 。
整数 n 是 4 的幂次方需满足:存在整数 x 使得 n == 4x
示例 1:
输入:n = 16
输出:true
示例 2:
输入:n = 5
输出:false
示例 3:
输入:n = 1
输出:true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/power-of-four
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
也想用简单一行的方法,但是没太想出来哈哈,就只能找二进制位的1在哪个位置了
class Solution {
public boolean isPowerOfFour(int n) {
//4的幂,就是统计这个1在第几位,如果是偶数位,就是4的幂
if(n <= 0)
return false;
int count = 1;
while((n & 1) != 1){
n >>= 1;
count++;
}
count++;
return n == 1 && count % 2 == 0;
}
}
官解的写法,构造一个奇数位都是1的整数,然后与n相与,如果是0,就表示是4的幂(是2的幂的前提下)
或者对3取余数,4的幂对3取余是1,如果是2的幂对3取余是2
class Solution {
public boolean isPowerOfFour(int n) {
return n > 0 && (n & (n - 1)) == 0 && (n & 0xaaaaaaaa) == 0;
//return n > 0 && (n & (n - 1)) == 0 && n % 3 == 1;
}
}
第243场周赛
这场咋说呢,也是前两道秒过吧,第三道能做但卡,第四道基本没咋看,和周六晚上的双周赛基本一个节奏,下次目标还是三道题,不过排名进步了哈哈
1880. 检查某单词是否等于两单词之和
题目描述
字母的 字母值 取决于字母在字母表中的位置,从 0 开始 计数。即,'a' -> 0、'b' -> 1、'c' -> 2,以此类推。
对某个由小写字母组成的字符串 s 而言,其 数值 就等于将 s 中每个字母的 字母值 按顺序 连接 并 转换 成对应整数。
例如,s = "acb" ,依次连接每个字母的字母值可以得到 "021" ,转换为整数得到 21 。
给你三个字符串 firstWord、secondWord 和 targetWord ,每个字符串都由从 'a' 到 'j' (含 'a' 和 'j' )的小写英文字母组成。
如果 firstWord 和 secondWord 的 数值之和 等于 targetWord 的数值,返回 true ;否则,返回 false 。
示例 1:
输入:firstWord = "acb", secondWord = "cba", targetWord = "cdb"
输出:true
解释:
firstWord 的数值为 "acb" -> "021" -> 21
secondWord 的数值为 "cba" -> "210" -> 210
targetWord 的数值为 "cdb" -> "231" -> 231
由于 21 + 210 == 231 ,返回 true
示例 2:
输入:firstWord = "aaa", secondWord = "a", targetWord = "aab"
输出:false
解释:
firstWord 的数值为 "aaa" -> "000" -> 0
secondWord 的数值为 "a" -> "0" -> 0
targetWord 的数值为 "aab" -> "001" -> 1
由于 0 + 0 != 1 ,返回 false
示例 3:
输入:firstWord = "aaa", secondWord = "a", targetWord = "aaaa"
输出:true
解释:
firstWord 的数值为 "aaa" -> "000" -> 0
secondWord 的数值为 "a" -> "0" -> 0
targetWord 的数值为 "aaaa" -> "0000" -> 0
由于 0 + 0 == 0 ,返回 true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/check-if-word-equals-summation-of-two-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
没啥好说的,变成数字,判断加法就行了
class Solution {
public boolean isSumEqual(String firstWord, String secondWord, String targetWord) {
int num1 = 0;
for(int i = 0; i < firstWord.length(); i++){
num1 = num1 * 10 + firstWord.charAt(i) - 'a';
}
int num2 = 0;
for(int i = 0; i < secondWord.length(); i++){
num2 = num2 * 10 + secondWord.charAt(i) - 'a';
}
int num3 = 0;
for(int i = 0; i < targetWord.length(); i++){
num3 = num3 * 10 + targetWord.charAt(i) - 'a';
}
return num1 + num2 == num3;
}
}
1881. 插入后的最大值
题目描述
给你一个非常大的整数 n 和一个整数数字 x ,大整数 n 用一个字符串表示。n 中每一位数字和数字 x 都处于闭区间 [1, 9] 中,且 n 可能表示一个 负数 。
你打算通过在 n 的十进制表示的任意位置插入 x 来 最大化 n 的 数值 。但 不能 在负号的左边插入 x 。
例如,如果 n = 73 且 x = 6 ,那么最佳方案是将 6 插入 7 和 3 之间,使 n = 763 。
如果 n = -55 且 x = 2 ,那么最佳方案是将 2 插在第一个 5 之前,使 n = -255 。
返回插入操作后,用字符串表示的 n 的最大值。
示例 1:
输入:n = "99", x = 9
输出:"999"
解释:不管在哪里插入 9 ,结果都是相同的。
示例 2:
输入:n = "-13", x = 2
输出:"-123"
解释:向 n 中插入 x 可以得到 -213、-123 或者 -132 ,三者中最大的是 -123 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-value-after-insertion
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
我当时还在想有0要怎么处理一下,结果一看没有0,那不用多说了
class Solution {
public String maxValue(String n, int x) {
//如果n是正数,就从左到右,如果找到大于的第一个数左边插入
//如果是负数,找到小于的第一个数左边插入
int l = n.length();
boolean flag = n.charAt(0) == '-' ? false : true;
int index = 0;
if(flag){
while(index < l){
char c = n.charAt(index);
if(x > c - '0')
break;
index++;
}
}else{
index = 1;
while(index < l){
char c = n.charAt(index);
if(x < c - '0')
break;
index++;
}
}
char[] s = new char[l + 1];
for(int i = 0; i <= l; i++){
if(i < index)
s[i] = n.charAt(i);
else if(i == index)
s[i] = (char)(x + 48);
else
s[i] = n.charAt(i - 1);
}
return new String(s);
}
}
1882. 使用服务器处理任务
题目描述
给你两个 下标从 0 开始 的整数数组 servers 和 tasks ,长度分别为 n 和 m 。servers[i] 是第 i 台服务器的 权重 ,而 tasks[j] 是处理第 j 项任务 所需要的时间(单位:秒)。
你正在运行一个仿真系统,在处理完所有任务后,该系统将会关闭。每台服务器只能同时处理一项任务。第 0 项任务在第 0 秒可以开始处理,相应地,第 j 项任务在第 j 秒可以开始处理。处理第 j 项任务时,你需要为它分配一台 权重最小 的空闲服务器。如果存在多台相同权重的空闲服务器,请选择 下标最小 的服务器。如果一台空闲服务器在第 t 秒分配到第 j 项任务,那么在 t + tasks[j] 时它将恢复空闲状态。
如果没有空闲服务器,则必须等待,直到出现一台空闲服务器,并 尽可能早 地处理剩余任务。 如果有多项任务等待分配,则按照 下标递增 的顺序完成分配。
如果同一时刻存在多台空闲服务器,可以同时将多项任务分别分配给它们。
构建长度为 m 的答案数组 ans ,其中 ans[j] 是第 j 项任务分配的服务器的下标。
返回答案数组 ans 。
示例 1:
输入:servers = [3,3,2], tasks = [1,2,3,2,1,2]
输出:[2,2,0,2,1,2]
解释:事件按时间顺序如下:
- 0 秒时,第 0 项任务加入到任务队列,使用第 2 台服务器处理到 1 秒。
- 1 秒时,第 2 台服务器空闲,第 1 项任务加入到任务队列,使用第 2 台服务器处理到 3 秒。
- 2 秒时,第 2 项任务加入到任务队列,使用第 0 台服务器处理到 5 秒。
- 3 秒时,第 2 台服务器空闲,第 3 项任务加入到任务队列,使用第 2 台服务器处理到 5 秒。
- 4 秒时,第 4 项任务加入到任务队列,使用第 1 台服务器处理到 5 秒。
- 5 秒时,所有服务器都空闲,第 5 项任务加入到任务队列,使用第 2 台服务器处理到 7 秒。
示例 2:
输入:servers = [5,1,4,3,2], tasks = [2,1,2,4,5,2,1]
输出:[1,4,1,4,1,3,2]
解释:事件按时间顺序如下:
- 0 秒时,第 0 项任务加入到任务队列,使用第 1 台服务器处理到 2 秒。
- 1 秒时,第 1 项任务加入到任务队列,使用第 4 台服务器处理到 2 秒。
- 2 秒时,第 1 台和第 4 台服务器空闲,第 2 项任务加入到任务队列,使用第 1 台服务器处理到 4 秒。
- 3 秒时,第 3 项任务加入到任务队列,使用第 4 台服务器处理到 7 秒。
- 4 秒时,第 1 台服务器空闲,第 4 项任务加入到任务队列,使用第 1 台服务器处理到 9 秒。
- 5 秒时,第 5 项任务加入到任务队列,使用第 3 台服务器处理到 7 秒。
- 6 秒时,第 6 项任务加入到任务队列,使用第 2 台服务器处理到 7 秒。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/process-tasks-using-servers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
每次看到这种一长串的题,感觉就是模拟了
然后我想的是把服务器放在优先队列中,按照权重和在servers数组中的位置排序;另外用一个哈希表存储<时间,服务器>的键值对,表示当前时间,哪几个服务器完成了工作
然后遍历时间,如果当前时间有服务器完成工作了,就放入优先队列中;如果当前有工作要完成,就去看优先队列中有没有服务器,如果有就安排到map集合中。
就这样,写了下面的代码,示例过了,但是提交超时了,但是不是数组很大的时候超时,而是不到十个数就超时了,那说明代码有问题,下面是当时写的代码:
class Solution {
public int[] assignTasks(int[] servers, int[] tasks) {
//模拟一下吧
//优先队列,放入服务器,按权重和下标排序
//然后遍历时间,如果可以分配服务器,就将服务器弹出,同时记录返回的时间,存入一个哈希表中
PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>(){
public int compare(int[] a, int[] b){
return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
}
});
int m = servers.length;
for(int i = 0; i < m; i++){
pq.offer(new int[]{servers[i], i});
}
Map<Integer, List<Integer>> map = new HashMap<>();
int n = tasks.length;
int[] res = new int[n];
int index = 0;
for(int i = 0; i < n; i++){
//当前时间,是否有工作完成,有工作完成,把服务器空闲出来
if(map.containsKey(i)){
List<Integer> ser = map.get(i);
map.remove(i);
for(Integer s : ser){
pq.offer(new int[]{servers[s], s});
}
}
while(index <= i){
if(!pq.isEmpty()){
res[index] = pq.peek()[1];
if(map.containsKey(i + tasks[index])){
List<Integer> list = map.get(i + tasks[index]);
list.add(pq.poll()[1]);
map.put(i + tasks[index], list);
}else{
List<Integer> list = new LinkedList<>();
list.add(pq.poll()[1]);
map.put(i + tasks[index], list);
}
index++;
}
}
if(index == n)
break;
}
return res;
}
}
应该是while那部分有问题,改一下看看行不行,简单改了一下,败给了超时,不过也在意料之中,因为时间我是一个一个加的。其实可以改成按tasks中一个个任务来,因为任务的处理是从左到右的,这里就不改了,题解思路也和我的思路差不多
这是我第一次改后的
class Solution {
public int[] assignTasks(int[] servers, int[] tasks) {
//模拟一下吧
//优先队列,放入服务器,按权重和下标排序
//然后遍历时间,如果可以分配服务器,就将服务器弹出,同时记录返回的时间,存入一个哈希表中
PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>(){
public int compare(int[] a, int[] b){
return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
}
});
int m = servers.length;
for(int i = 0; i < m; i++){
pq.offer(new int[]{servers[i], i});
}
Map<Long, List<Integer>> map = new HashMap<>();
int n = tasks.length;
int[] res = new int[n];
int index = 0;
//tasks长度最大为200000,m,n的值最大为200000,所以时间最多400000
//不对,应该是乘
for(long i = 0; i < 40000000001l; i++){
//当前时间,是否有工作完成,有工作完成,把服务器空闲出来
if(map.containsKey(i)){
List<Integer> ser = map.get(i);
map.remove(i);
for(Integer s : ser){
pq.offer(new int[]{servers[s], s});
}
}
//如果当前任务的开工时间小于i,表示可以开工
while(index <= i){
//如果有服务器空闲
if(!pq.isEmpty()){
//取出第一个服务器的编号
res[index] = pq.peek()[1];
//如果哈希表中,存在这个时间点,就把这个服务器插入list集合中
if(map.containsKey(i + tasks[index])){
List<Integer> list = map.get(i + tasks[index]);
list.add(pq.poll()[1]);
map.put(i + tasks[index], list);
//如果没有这个编号,创建这个集合
}else{
List<Integer> list = new LinkedList<>();
list.add(pq.poll()[1]);
map.put(i + tasks[index], list);
}
index++;
if(index == n)
break;
//如果没有,就直接跳出
}else{
break;
}
}
if(index == n)
break;
}
return res;
}
}
然后我看题解发现,只要将当服务器都被占用时,时间直接调成下一个服务器空闲的时间,就可以AC了,然后我就把原来的HashMap改成TreeMap,这样可以使服务器时间排序,然后每次服务器都被占用时,时间就可以跳成map.firstKey(),不过这个方法我还是第一次用
然后直接双百了哈哈
class Solution {
public int[] assignTasks(int[] servers, int[] tasks) {
//模拟一下吧
//优先队列,放入服务器,按权重和下标排序
//然后遍历时间,如果可以分配服务器,就将服务器弹出,同时记录返回的时间,存入一个哈希表中
PriorityQueue<int[]> pq = new PriorityQueue<>(new Comparator<int[]>(){
public int compare(int[] a, int[] b){
return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
}
});
int m = servers.length;
for(int i = 0; i < m; i++){
pq.offer(new int[]{servers[i], i});
}
TreeMap<Long, List<Integer>> map = new TreeMap<>();
int n = tasks.length;
int[] res = new int[n]以上是关于LeetCode342. 4的幂 / 第243场周赛的主要内容,如果未能解决你的问题,请参考以下文章