第 k 个数
问题描述: 有些数的素因子只有 3,5,7,请设计一个算法找出第 k 个数。注意,不是必须有这些素因子,而是必须不包含其他的素因子。例如,前几个数按顺序应该是 1,3,5,7,9,15,21。(by leetcode 17.09)
示例 1:
输入: k = 5
输出: 9
思路: 建立三个指针,往数组中填数。找到最小的,指定指针往后移动。
var getKthMagicNumber = function(k) {
let k1=0,k2=0;k3=0,data=[1];
while(data.length<k){
let temp=Math.min(data[k1]*3,data[k2]*5,data[k3]*7);
if(temp==data[k1]*3)k1++;
if(temp==data[k2]*5)k2++;
if(temp==data[k3]*7)k3++;
data.push(temp)
}
return data[k-1]
};
柠檬水找零
问题描述: 在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
注意,一开始你手头没有任何零钱。
给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。(by leetcode 860)
示例 1:
输入:bills = [5,5,5,10,20]
输出:true
解释:
前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。
思路:
/**
\* @param {number[]} bills
\* @return {boolean}
*/
var lemonadeChange = function(bills) {
let arr={
'5':0,
'10':0
}
for(let i=0;i<bills.length;i++){
if(bills[i]==5){
arr['5']++;
}
if(bills[i]==10){
if(!arr['5'])return false;
arr['5']--;
arr['10']++;
}
if(bills[i]==20){
if(!arr['5'])return false;
if(arr['10']){
arr['5']--;
arr['10']--;
}
else{
if( arr['5']<3)return false;
arr['5']-=3;
}
}
}
return true
};
煎饼排序
问题描述: 给你一个整数数组 arr ,请使用 煎饼翻转 完成对数组的排序。(by leetcode 969)
一次煎饼翻转的执行过程如下:
- 选择一个整数
k,1 <= k <= arr.length - 反转子数组
arr[0...k-1](下标从 0 开始)
例如,arr = [3,2,1,4] ,选择 k = 3 进行一次煎饼翻转,反转子数组 [3,2,1] ,得到 arr = [**1**,**2**,**3**,4] 。
以数组形式返回能使 arr 有序的煎饼翻转操作所对应的 k 值序列。任何将数组排序且翻转次数在 10 * arr.length 范围内的有效答案都将被判断为正确。
示例 1:
输入:[3,2,4,1]
输出:[4,2,4,3]
解释:
我们执行 4 次煎饼翻转,k 值分别为 4,2,4,和 3。
初始状态 arr = [3, 2, 4, 1]
第一次翻转后(k = 4):arr = [1, 4, 2, 3]
第二次翻转后(k = 2):arr = [4, 1, 2, 3]
第三次翻转后(k = 4):arr = [3, 2, 1, 4]
第四次翻转后(k = 3):arr = [1, 2, 3, 4],此时已完成排序。
思路:
方案:第一轮,找到最大的,然后翻转它之前的(包括他本身),此时本轮最大的跑到最前面。再整体翻转全部。
第二轮,忽略最后一位,重复第一轮的操作。
第三轮,忽略倒数两位,重复第一轮操作,以此类推,直到只剩一位,不需要操作。
/**
* @param {number[]} arr
* @return {number[]}
*/
//翻转
function reverse(arr,index,ind){
for(let i=0,j=index-1;i<j;i++,j--){
[arr[i],arr[j]]=[arr[j],arr[i]];
ind[arr[i]]=i;
ind[arr[j]]=j;
}
}
var pancakeSort = function(arr) {
let index=[0];
let ret=[];
for(let i=0;i<arr.length;i++){
index[arr[i]]=i;//将值用下标记录(没有值为0的,因此长度加1)
}
for(let i=arr.length;i>=1;i--){//针对每一轮处理翻转,只剩一个值不需要翻转
if(index[i]==i+1)continue;//值在正确的位置上,不需要翻转
if(i+1!==1){
ret.push(index[i]+1);//
reverse(arr,index[i]+1,index);}//翻转i+1位
if(i!=1){
ret.push(i);
reverse(arr,i,index);
}
}
return ret;
};
任务调度器
问题描述: 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个任务,或者处于待命状态。
然而,两个 相同种类 的任务之间必须有长度为整数 n 的冷却时间,因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。(by leetcode 621)
你需要计算完成所有任务所需要的 最短时间 。
示例 1:
输入:tasks = ["A","A","A","B","B","B"], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
思路:
只有两种情况:1.用任务填充待命区时,待命区还有空位。2.填满为任务总长度。
因此就是取两者最长的值。
/**
* @param {character[]} tasks
* @param {number} n
* @return {number}
*/
var leastInterval = function(tasks, n) {
let arrMap=new Array(26).fill(0);
for(let i=0;i<tasks.length;i++){
arrMap[tasks[i].charCodeAt(0)-'A'.charCodeAt(0)]++;
}
////console.log(arrMap)
let max=0;
let maxlength=0;
for(let i=0;i<arrMap.length;i++){
if(arrMap[i]>max){
maxlength=1;
max=arrMap[i];
}else if(arrMap[i]==max){
maxlength++
}
}
//console.log(maxlength)
return Math.max((max-1)*(n+1)+maxlength,tasks.length)
};