全字母句 指包含英语字母表中每个字母至少一次的句子。给你一个仅由小写英文字母组成的字符串 sentence ,请你判断 sentence 是否为 全字母句 。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:sentence = "thequickbrownfoxjumpsoverthelazydog"
输出:true
解释:sentence 包含英语字母表中每个字母至少一次。
示例 2:
输入:sentence = "leetcode"
输出:false
看到题目大概就知道怎么做了,其实就是判断一个字符串中是否包含26个字母,包含的话就输出true,不包含就输出false。可以借助HashSet来解决,设置一个count来计数字符数,遍历字符串,将每一个字符都放入到HashSet中,如果可以顺利放入,就将count加一,如果不能顺利放入,说明此字符已经在HashSet中了,继续遍历,直到结束。最后判断count是否等于26,输出结果。
class Solution {
public boolean checkIfPangram(String sentence) {
//使用HastSet来解决
HashSet<Character> result = new HashSet<>();
int len = sentence.length();
int count = 0;
for(int i=0;i<len;i++){
if(result.add(sentence.charAt(i))!=false)//说明当前字符还未加入到HashSet中,那么count就加一
count++;
}
if(count !=26)
return false;
else return true;
}
}
夏日炎炎,小男孩 Tony 想买一些雪糕消消暑。商店中新到 n 支雪糕,用长度为 n 的数组 costs 表示雪糕的定价,其中 costs[i] 表示第 i 支雪糕的现金价格。Tony 一共有 coins 现金可以用于消费,他想要买尽可能多的雪糕。给你价格数组 costs 和现金量 coins ,请你计算并返回 Tony 用 coins 现金能够买到的雪糕的最大数量 。
注意:Tony 可以按任意顺序购买雪糕。
示例 1:
输入:costs = [1,3,2,4,1], coins = 7
输出:4
解释:Tony 可以买下标为 0、1、2、4 的雪糕,总价为 1 + 3 + 2 + 1 = 7
示例2:
输入:costs = [10,6,8,7,7,8], coins = 5
输出:0
解释:Tony 没有足够的钱买任何一支雪糕。
示例 3:
输入:costs = [1,6,3,1,2,5], coins = 20
输出:6
解释:Tony 可以买下所有的雪糕,总价为 1 + 6 + 3 + 1 + 2 + 5 = 18 。
提示:
costs.length == n
1 <= n <= 105
1 <= costs[i] <= 105
1 <= coins <= 108
本题考查的点是贪心。 首先先对costs数组进行排序,从小到大来排序,然后拿coins依次减,直到减不了为止,使用count来计数。
class Solution {
public int maxIceCream(int[] costs, int coins) {
//先对数组排序,然后依次来减
int len = costs.length;
if(coins==0) return 0; //自己的coins为0时,直接返回0
Arrays.sort(costs);
if(costs[0]>coins) return 0;//雪糕的最小价格都大于coins,自然是买不起任何一个
int count = 0;
for(int i =0;i<len;i++){
if(coins>=costs[i]){
count++;
coins = coins-costs[i];
}
}
return count;
}
}
给你一个二维数组 tasks ,用于表示 n 项从 0 到 n - 1 编号的任务。其中 tasks[i] = [enqueueTimei, processingTimei] 意味着第 i 项任务将会于 enqueueTimei 时进入任务队列,需要 processingTimei 的时长完成执行。
现有一个单线程 CPU ,同一时间只能执行 最多一项 任务,该 CPU 将会按照下述方式运行:
示例 1:
输入:tasks = [[1,2],[2,4],[3,2],[4,1]]
输出:[0,2,3,1]
解释:事件按下述流程运行:
- time = 1 ,任务 0 进入任务队列,可执行任务项 = {
0}
- 同样在 time = 1 ,空闲状态的 CPU 开始执行任务 0 ,可执行任务项 = {
}
- time = 2 ,任务 1 进入任务队列,可执行任务项 = {
1}
- time = 3 ,任务 2 进入任务队列,可执行任务项 = {
1, 2}
- 同样在 time = 3 ,CPU 完成任务 0 并开始执行队列中用时最短的任务 2 ,可执行任务项 = {
1}
- time = 4 ,任务 3 进入任务队列,可执行任务项 = {
1, 3}
- time = 5 ,CPU 完成任务 2 并开始执行队列中用时最短的任务 3 ,可执行任务项 = {
1}
- time = 6 ,CPU 完成任务 3 并开始执行任务 1 ,可执行任务项 = {
}
- time = 10 ,CPU 完成任务 1 并进入空闲状态
示例 2:
输入:tasks = [[7,10],[7,12],[7,5],[7,4],[7,2]]
输出:[4,3,2,0,1]
解释:事件按下述流程运行:
- time = 7 ,所有任务同时进入任务队列,可执行任务项 = {
0,1,2,3,4}
- 同样在 time = 7 ,空闲状态的 CPU 开始执行任务 4 ,可执行任务项 = {
0,1,2,3}
- time = 9 ,CPU 完成任务 4 并开始执行任务 3 ,可执行任务项 = {
0,1,2}
- time = 13 ,CPU 完成任务 3 并开始执行任务 2 ,可执行任务项 = {
0,1}
- time = 18 ,CPU 完成任务 2 并开始执行任务 0 ,可执行任务项 = {
1}
- time = 28 ,CPU 完成任务 0 并开始执行任务 1 ,可执行任务项 = {
}
- time = 40 ,CPU 完成任务 1 并进入空闲状态
看到题目到理解题目,其实还是比较容易的,就是在实现起来有点复杂,代码编写的过程中需要注意一些细节的地方。
PriorityQueue:基于优先级堆的无限优先级queue。优先级队列的元素根据它们的有序natural ordering,或由一个Comparator在队列构造的时候提供,这取决于所使用的构造方法。优先队列不允许null元素。依靠自然排序的优先级队列也不允许插入不可比较的对象
解法一:借助数组
class Solution {
public int[] getOrder(int[][] tasks) {
int n = tasks.length;
int[][] task = new int[n][3];//存原数组,并加入id
for (int i = 0; i < tasks.length; i++) {
task[i][0] = tasks[i][0];
task[i][1] = tasks[i][1];
task[i][2] = i;
}
Arrays.sort(task, (x,y)->x[0]-y[0]);//先按照起始时间排序
PriorityQueue<Integer> heap = new PriorityQueue<>((x,y)->{
//优先队列
if(task[x][1]==task[y][1]){
//当两者的需要的时间一样的时候,先执行id小的。
return task[x][2]-task[y][2];
}
return task[x][1]-task[y][1];
});
int now = 1;
int[] ret = new int[n];//存最终的结果
int i = 0;//遍历线程任务
int j = 0;//存线程执行顺序
while(i<n){
while(i<n&&(heap.isEmpty()||now>=task[i][0])){
now = Math.max(now,task[i][0]);//获取当前时间
heap.add(i++);
}
int[]task1 = task[heap.poll()];//栈顶为当前第i线程
ret[j++] = task1[2];//将id加入到ret中
now += task1[1];//此刻的时间为now+task1[1]
}
while(!heap.isEmpty()){
//说明最后还有线程在栈顶中
ret[j++] = task[heap.poll()][2];
}
return ret;
}
}
解法二:借助类
class Solution {
//构造任务类 Java面向对象编程
class Task {
public int index;//索引属性
public int eTime;//线程开始时间
public int pTime;//线程完成所需时间
public Task(int index,int eTime, int pTime) {
//有参构造
this.index = index;
this.eTime = eTime;
this.pTime = pTime;
}
}
public int[] getOrder(int[][] tasks) {
PriorityQueue<Task> queue = new PriorityQueue<>((a,b) -> {
if (a.pTime == b.pTime) return a.index - b.index;else return a.pTime - b.pTime;});//构造队列,如果线程完成所需时间一样,那么索引小的先开始执行
int[] res = new int[tasks.length];//存放最终的执行顺序
int count = 0;//计数
int cur = 0;
ArrayList<Task> list = new ArrayList<>();
for (int i = 0; i < tasks.length; i++)
list.add(new Task(i, tasks[i][0], tasks[i][1]));
// Collections.sort(list,Comparator.comparingInt(a->a.eTime));
list.sort(Comparator.comparingInt(a -> a.eTime));//根据线程开始时间排序
int nowTime = list.get(0).eTime;//第一个线程开始的时间,即为现在的时间。
while (count < tasks.length && list.get(count).eTime <= nowTime)
queue.add(list.get(count++));
while (!queue.isEmpty()){
Task t = queue.remove();
nowTime += t.pTime;
res[cur++] = t.index;
if (queue.isEmpty() && count < tasks.length && list.get(count).eTime > nowTime)
//以下三个均可
nowTime += list.get(count).eTime;
//nowTime = list.get(count).eTime;
//nowTime +=list.get(count).pTime;
while (count < tasks.length && list.get(count).eTime <= nowTime)//将线程加入队列中
queue.add(list.get(count++));
}
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 。返回上述列表的 异或和 。
示例 1:
输入:arr1 = [1,2,3], arr2 = [6,5]
输出:0
解释:列表 = [1 AND 6, 1 AND 5, 2 AND 6, 2 AND 5, 3 AND 6, 3 AND 5] = [0,1,2,0,2,1] ,
异或和 = 0 XOR 1 XOR 2 XOR 0 XOR 2 XOR 1 = 0 。
示例 2:
输入:arr1 = [12], arr2 = [4]
输出:4
解释:列表 = [12 AND 4] = [4] ,异或和 = 4 。
利用xor和and之间的分配律:(a xor b) and c = (a and c) xor (b and c)
来简化求解。
原式最终可以被化简为:
(a_1 xor a_2 xor … xor a_n) and (b_1 xor b_2 xor … xor b_m)
class Solution {
public int getXORSum(int[] arr1, int[] arr2) {
int sum = 0;
int result = 0;
for (int i : arr2) {
//第一步
sum^=i;
}
for(int i:arr1){
//第二步
result ^= (i&sum);
}
return result;
}
}
通过本次周赛,又加深了自己对Java的学习,有些题目从有思路->用编程的方式写出来,还是有一个过程的,说明思想到编程的转换做的害不够好。对一些比较常用的集合,在平时的编程中要多加的使用,这样可以加深自己的理解。
时间:2021/4/19