全字母句 指包含英语字母表中每个字母至少一次的句子。
给你一个仅由小写英文字母组成的字符串 sentence ,请你判断 sentence 是否为 全字母句 。
如果是,返回 true ;否则,返回 false 。
好久没更新博客了,倒不是因为懒。实在是刷到现在每天再做三道新题已经比较困难了。最近这段时间也都是被毕业和工作的事情压着,每周能有时间搞搞周赛已经很不错了。最近又被几家大厂待定了,今天突然有看开的感觉了。可能是因为天气好的原因,心情也跟着好了起来。不管怎么样,把自己能做到的做到就好了。
周赛第一题,用一个数组记录一下就好了,简单题。
class Solution {
public boolean checkIfPangram(String sentence) {
int[] map = new int[26];
for(char c : sentence.toCharArray()){
map[c - 'a']++;
}
for(int i = 0; i < map.length; i++){
if (map[i] == 0) return false;
}
return true;
}
}
夏日炎炎,小男孩 Tony 想买一些雪糕消消暑。
商店中新到 n 支雪糕,用长度为 n 的数组 costs 表示雪糕的定价,其中 costs[i] 表示第 i 支雪糕的现金价格。Tony 一共有 coins 现金可以用于消费,他想要买尽可能多的雪糕。
给你价格数组 costs 和现金量 coins ,请你计算并返回 Tony 用 coins 现金能够买到的雪糕的 最大数量 。
注意:Tony 可以按任意顺序购买雪糕。
复盘的时候看到雪糕,突然想吃雪糕了,等下去买根吃吧。这题一开始以为是dp,后来觉得简单贪心就好了,也是比较简单的。
class Solution {
public int maxIceCream(int[] costs, int coins) {
Arrays.sort(costs);
int res = 0, i = 0;
while (i < costs.length){
coins -= costs[i++];
if (coins < 0) break;
res++;
}
return res;
}
}
给你一个二维数组 tasks ,用于表示 n 项从 0 到 n - 1 编号的任务。其中 tasks[i] = [enqueueTimei, processingTimei] 意味着第 i 项任务将会于 enqueueTimei 时进入任务队列,需要 processingTimei 的时长完成执行。
现有一个单线程 CPU ,同一时间只能执行 最多一项 任务,该 CPU 将会按照下述方式运行:
如果 CPU 空闲,且任务队列中没有需要执行的任务,则 CPU 保持空闲状态。
如果 CPU 空闲,但任务队列中有需要执行的任务,则 CPU 将会选择 执行时间最短 的任务开始执行。如果多个任务具有同样的最短执行时间,则选择下标最小的任务开始执行。
一旦某项任务开始执行,CPU 在 执行完整个任务 前都不会停止。
CPU 可以在完成一项任务后,立即开始执行一项新任务。
返回 CPU 处理任务的顺序。
这题思路是不难的,但是编写的时候要考虑一下各种情况。思路其实就是模拟,用一个堆保存当前可以执行的任务,从中取出最小就行了。实际上感觉就是最短作业优先的实现。
class Solution {
class Node{
int index;
int start;
int time;
public Node(int index, int start, int time){
this.index = index;
this.start = start;
this.time = time;
}
}
public int[] getOrder(int[][] tasks) {
int n = tasks.length, i = 0, idx = 0;
int[] res = new int[n];
Node[] help = new Node[n];
//用一个Node保存
for(int j = 0; j < n; j++){
help[j] = new Node(j, tasks[j][0], tasks[j][1]);
}
//对Node的开始时间排序
Arrays.sort(help, (x, y) -> (x.start - y.start));
//堆里先按需要的作业时间排序,再按下标排序
PriorityQueue<Node> queue = new PriorityQueue<>((x, y) -> (x.time == y.time ? x.index - y.index : x.time - y.time));
int now = 1;
while (i < n || !queue.isEmpty()){
//如果说当前时间小于后一个开始时间,就更新时间为后一个开始时间
if (queue.isEmpty() && i < n && help[i].start > now){
now = help[i].start;
}
//小于当前时间的都能入队
while (i < n && help[i].start <= now){
queue.offer(help[i]);
i++;
}
//从队里取出最短作业的任务,更新一下时间
if (!queue.isEmpty()){
Node temp = queue.poll();
res[idx++] = temp.index;
if (now + temp.time >= now){
now = now + temp.time;
}
}
}
return res;
}
}
列表的 异或和(XOR sum)指对所有元素进行按位 XOR 运算的结果。如果列表中仅有一个元素,那么其 异或和 就等于该元素。
例如,[1,2,3,4] 的 异或和 等于 1 XOR 2 XOR 3 XOR 4 = 4 ,而 3 的 异或和 等于 3 。
给你两个下标 从 0 开始 计数的数组 arr1 和 arr2 ,两数组均由非负整数组成。
根据每个 (i, j) 数对,构造一个由 arr1[i] AND arr2[j](按位 AND 运算)结果组成的列表。其中 0 <= i < arr1.length 且 0 <= j < arr2.length 。
返回上述列表的 异或和 。
难得一道很简单的hard题,最多就是medium感觉。首先看数据范围肯定不能暴力,然后可以利用异或运算的分配率,先算一下arr2的异或和,在和arr1的每一个元素做与运算后再异或就行了。
class Solution {
public int getXORSum(int[] arr1, int[] arr2) {
int sum = 0;
//先算下arr2的异或和
for(int num : arr2){
sum ^= num;
}
int res = 0;
//再和arr1的每一个元素做与运算,再异或
for(int num : arr1){
res ^= (num & sum);
}
return res;
}
}
给你一个整数数组 nums (下标从 0 开始)。每一次操作中,你可以选择数组中一个元素,并将它增加 1 。
比方说,如果 nums = [1,2,3] ,你可以选择增加 nums1 得到 nums = [1,3,3] 。
请你返回使 nums 严格递增 的 最少 操作次数。
我们称数组 nums 是 严格递增的 ,当它满足对于所有的 0 <= i < nums.length - 1 都有 nums[i] < nums[i+1] 。一个长度为 1 的数组是严格递增的一种特殊情况。
简单题,因为只能做递增运算,所以吐过当前数大于之前的元素就不变,否则加到之前元素加1就行了。
class Solution {
public int minOperations(int[] nums) {
int n = nums.length, res = 0, prev = nums[0];
for(int i = 1; i < n; i++){
if (nums[i] <= prev){
res += prev + 1 - nums[i];
prev = prev + 1;
}else{
prev = nums[i];
}
}
return res;
}
}
给你一个数组 points ,其中 points[i] = [xi, yi] ,表示第 i 个点在二维平面上的坐标。多个点可能会有 相同 的坐标。
同时给你一个数组 queries ,其中 queries[j] = [xj, yj, rj] ,表示一个圆心在 (xj, yj) 且半径为 rj 的圆。
对于每一个查询 queries[j] ,计算在第 j 个圆 内 点的数目。如果一个点在圆的 边界上 ,我们同样认为它在圆 内 。
请你返回一个数组 answer ,其中 answer[j]是第 j 个查询的答案
也是简单题,根据数据范围,算下每个点到圆心的距离,然后和半径比一下就行了。
class Solution {
public int[] countPoints(int[][] points, int[][] queries) {
int n = queries.length, index = 0;
int[] res = new int[n];
for(int[] query : queries){
int x1 = query[0], y1 = query[1], count = 0;
for(int[] point : points){
int x2 = point[0], y2 = point[1];
double dist = distance(x1, y1, x2, y2);
if (dist <= query[2]){
count++;
}
}
res[index++] = count;
}
return res;
}
private double distance(int x1, int y1, int x2, int y2){
int temp = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
return Math.sqrt(temp);
}
}
给你一个 有序 数组 nums ,它由 n 个非负整数组成,同时给你一个整数 maximumBit 。你需要执行以下查询 n 次:
找到一个非负整数 k < 2maximumBit ,使得 nums[0] XOR nums1 XOR … XOR nums[nums.length-1] XOR k 的结果 最大化 。k 是第 i 个查询的答案。
从当前数组 nums 删除 最后 一个元素。
请你返回一个数组 answer ,其中 answer[i]是第 i 个查询的结果。
这题一开始看到删除,以为要先保存异或前缀。其实不用,从后往前填答案即可。然后想一想不大于给定maximumBit的数,一定可以使得当前异或的结果的后几位取反,那么贪心地把小于maximumBit的低位都取反就行了。
class Solution {
public static int[] getMaximumXor(int[] nums, int maximumBit) {
int n = nums.length;
int[] help = new int[n];
int[] res = new int[n];
int sum = 0;
//前缀异或,其实不需要
for(int i = 0; i < nums.length; i++){
sum ^= nums[i];
help[i] = sum;
}
int index = 0;
for(int i = n - 1; i >= 0; i--){
int temp = 0;
for(int j = 31; j >= 0; j--){
int shift = ((help[i] >> j) & 1);
//高位都不动,低位取反即可
if (j >= maximumBit){
temp += shift * (1 << j);
}else{
temp += (shift ^ 1) * (1 << j);
}
}
res[index++] = temp;
}
return res;
}
}