20210919每日一题
650. 只有两个键的键盘
模拟算法。
A;
AA;
AAA OR AAAA;
直接用代码模拟操作即可。
class Solution {
/**
问题转换 一开始 num = 1只有+1 操作可选(1,num)
贪心算法
n = 3 n = n-1=2; lastcopy = 1; allcopy = 1
n = 2 n = n-1=1; lastcopy = 1; allcopy = 2 (allcopy>n&& n%allcopy==0)才可以使用allcopy
只有2的平方可以实现快速对折
*/
public int minSteps(int n) {
int step = 0;
int copy = 0;
int countA = 1;
while(countA<n){
if((n-countA)%countA== 0){
copy = countA;
// 操作也算一次
step++;
}
countA+=copy;
step++;
}
return step;
}
}
剑指 Offer 61. 扑克牌中的顺子
在一定规则下判断数组是否为递增数组。
class Solution {
/**
[0,0,2,2,5]
*/
public boolean isStraight(int[] nums) {
Arrays.sort(nums);
int count = 0;
int last = 0;
for(int i =0;i<nums.length;i++){
if(nums[i] == 0){
count++;
}else if(last ==0){
last = nums[i];
}else{
// 默认找到了第一个非零数。处理第二个
if(last==nums[i]) return false;
if(nums[i]-last>1){
count-=(nums[i]-last-1);
if(count<0)return false;
}
}
last = nums[i];
}
return true;
}
}
周赛
5876. 数组美丽值求和
读题时,“对于所有”这四个字的理解十分关键。
逆向思考,如果nums[i]都大于左侧的最大值,那么左侧必定存在不相邻的小于nums[i]的一个数。
同理,如果nums[i]小于右侧的最小值,那么必定存在不相邻大于nums[i]的一个数。
碰到寻找左侧最值和右侧最值,可以考虑动态规划数组来维护 !
class Solution {
/**
如果 nums[i] >左侧的最大值 并且<右侧的最小值,那么一定属于+=2
用动态规划的思想维护左侧最大值 和右侧最小值
*/
public int sumOfBeauties(int[] nums) {
int res = 0;
int len = nums.length;
int[] maxleft = new int[len];
int[] minright = new int[len];
Arrays.fill(minright,Integer.MAX_VALUE);
// dp数组存储左侧最大值
for(int i = 1;i<len;i++){
maxleft[i] = Math.max(maxleft[i-1],nums[i-1]);
}
//dp数组存储右侧最小值
for(int i = len-2;i>0;i--){
minright[i] = Math.min(minright[i+1],nums[i+1]);
}
// 遍历数组
for(int i = 1;i<=len-2;i++){
if(nums[i]>maxleft[i]&&nums[i]<minright[i]){
res+=2;
}else if(nums[i]>nums[i-1]&&nums[i]<nums[i+1]){
res++;
}
}
return res;
}
}