1.所有数对中 数位差之和()
题意:
给定一个nums数组,计算中所有整数数对中 数位差的个数之和;
数位差:某一位上的数字不一样就记作数位差。
eg:12 22; 十位上不一样,数位差为1
思路:
首先计算出一个数字有多少位(题目中给出所有数字的位数都相同这个条件)
然后统计每一位上0-9的个数
最后就可以计算出数位差的个数。
比如说:个位等于0有x个,那么不等于0就有nums.size - x 个,那么数位差就有x*(nums.size-x)/2个
以此类推先计算个位上的。然后计算十位上的...
代码:
class Solution {
public long sumDigitDifferences(int[] nums) {
//nums中整数都有相同的长度
long res=0;
int size=nums.length;
int[][] cnt=new int[Integer.toString(nums[0]).length()][10];
for(int num:nums){
int index=0;
while(num>0){
cnt[index++][num%10]++;
num/=10;
}
}
for(int i=0;i<cnt.length;i++){
for(int j=0;j<10;j++){
res+=(long)cnt[i][j]*(size-cnt[i][j]);
}
}
return res>>1;
}
}
2.定长子串中原因的最大数目
给你字符串 s
和整数 k
。
请返回字符串 s
中长度为 k
的单个子字符串中可能包含的最大元音字母数。
英文中的 元音字母 为(a
, e
, i
, o
, u
)。
思路:
1.对字符串中的字符循环,判断是不是元音字母;如果是的话,元音字母数量+1;
2.此时判断滑动窗口的长度是否等于k
2.1 如果等于 就要判断s.charAt(left)是否是元音字母 如果是的话 数量-1;
2.2 如果小于 继续循环
3.right++,窗口继续往右扩展
代码:
class Solution {
public int maxVowels(String s, int k) {
int left = 0;
int right = 0;
int res = 0;
int amount = 0;
while (right < s.length()) {
char ch = s.charAt(right);
if (isYy(ch)) amount++;
if (right - left + 1 == k) {
res = Math.max(res, amount);
if (isYy(s.charAt(left)))
amount -= 1;
left++;
}
right++;
}
return res;
}
public boolean isYy(char ch) {
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u')
return true;
return false;
}
}
3.大小为K且平均值大于等于阈值的子数组数目
给你一个整数数组 arr
和两个整数 k
和 threshold
。
请你返回长度为 k
且平均值大于等于 threshold
的子数组数目。
思路:
对数组遍历循环,当窗口的长度==k的时候,判断平均值是否大于等于阈值,如果大于等于res++;然后left++,num-=nums[left]
代码:
class Solution {
public int numOfSubarrays(int[] arr, int k, int threshold) {
int res = 0;
int left = 0;
int right = 0;
int sum = 0;
while (right < arr.length) {
sum += arr[right];
if (right - left + 1 == k) {
if (sum >= threshold * k) {
res++;
}
sum -= arr[left];
left++;
}
right++;
}
return res;
}
}
4.拆炸弹
题意:
你有一个炸弹需要拆除,时间紧迫!你的情报员会给你一个长度为 n
的 循环 数组 code
以及一个密钥 k
。
如果k>0,数组中下标为index的值为后k位数字(>nums.length-1就返前来)的和;
如果k=0,数组中的值都为0;
如果k<0,数组中下标为index的值为前k位数字(<0折后去)的和
思路:
仍然使用固定长度的滑动窗口的思路;
首先对K进行判断,有三种情况;
k>0,开始进行循环遍历数组中的每一个数字,当right-left+1==k或者right+len-left+1==k的时候,res[(left-1)%k]==sum,循环的条件为index<nums.length+k-1(要使数组上每一个位置都有新的和)
k<0,同理
代码:
class Solution {
public int[] decrypt(int[] code, int k) {
int[] res=new int[code.length];
int len=code.length;
int left=0;
int right=0;
int sum=0;
int index=0;
if(k==0)return res;
else if(k>0){
while(index<code.length+k-1){
sum+=code[right];
System.out.println(sum);
if(right-left+1==k||right+len-left+1==k){
res[(left-1+len)%len]=sum;
sum-=code[left%len];
left=(left+1)%len;
}
right=(right+1)%len;
index++;
}
}else{
k=-k;
while(index<code.length+k-1){
sum+=code[right];
System.out.println(sum);
if(right-left+1==k||right+len-left+1==k){
res[(right+1)%len]=sum;
sum-=code[left];
left=(left+1)%len;
}
right=(right+1)%len;
index++;
}
}
return res;
}
}
模版:
class Solution {
public int numOfSubarrays(int[] arr, int k, int threshold) {
int res = 0;
int left = 0;
int right = 0;
int sum = 0;
while (right < arr.length) {
//1. 根据题目中的要求来计算
xxxxxxxx
//2. 此时判断窗口的大小是否等于题目中要求的
if (right - left + 1 == 窗口长度大小) {
if (条件) {
res++;
}
//3.窗口左边的边界移动
sum -= arr[left];
left++;
}
//4. 窗口右边的边界移动
right++;
}
return res;
}
}