496、下一个更大元素 I
nums1
中数字 x
的 下一个更大元素 是指 x
在 nums2
中对应位置 右侧 的 第一个 比 x
大的元素。给你两个 没有重复元素 的数组 nums1
和 nums2
,下标从 0 开始计数,其中nums1
是 nums2
的子集。对于每个 0 <= i < nums1.length
,找出满足 nums1[i] == nums2[j]
的下标 j
,并且在 nums2
确定 nums2[j]
的 下一个更大元素 。如果不存在下一个更大元素,那么本次查询的答案是 -1
。返回一个长度为 nums1.length
的数组 ans
作为答案,满足 ans[i]
是如上所述的 下一个更大元素 。
示例3:
题意解释:找到nums1[i]==nums2[j]后,判断nums2[j]后面的数是否有大于nums1[i]的,有则返回那个数,没有则返回-1
找到目标就退出循环用while比较好,用for的话,找到目标退出循环要利用break。
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
//正推:找到nums1[i] == nums2[j]后判断nums2后面的数是否有一个数大于nums1[i]
//反推:找到nums1[i] == nums2[j]后如果nums1[i]一直大于nums2[j+1],那么就会因超出数组长度而返回-1。如果满足条件,则结束循环输出该数
int []res=new int[nums1.length];
for(int i=0;i<nums1.length;i++){
int j=0;
while(j<nums2.length&&nums1[i]!=nums2[j]){
j++;
}
while(j+1<nums2.length&&nums1[i]>nums2[j+1]){
j++;
}
res[i]=j+1<nums2.length?nums2[j+1]:-1;
}
return res;
}
}
/*--------------------------------------*/
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
//正推:找到nums1[i] == nums2[j]后判断nums2后面的数是否有一个数大于nums1[i]
//反推:找到nums1[i] == nums2[j]后如果nums1[i]一直大于nums2[j+1],那么就会因超出数组长度而返回-1。如果满足条件,则结束循环输出该数
int []res=new int[nums1.length];
for(int i=0;i<nums1.length;i++){
int j=0;
for(j=0;j<nums2.length;j++){
if(nums1[i]==nums2[j]){
break;
}
}
for(;j+1<nums2.length;j++){
if(nums1[i]<nums2[j+1]){
break;
}
}
res[i]=j+1<nums2.length?nums2[j+1]:-1;
}
return res;
}
}
500、键盘行
给你一个字符串数组 words
,只返回可以使用在 美式键盘 同一行的字母打印出来的单词。键盘如下图所示。
美式键盘 中:
- 第一行由字符
"qwertyuiop"
组成。 - 第二行由字符
"asdfghjkl"
组成。 - 第三行由字符
"zxcvbnm"
组成。
题意:若数组中的单词的字母都在同一行,则输出,否则不输出。(Hello中H和e在不同行,Alaska所有字母都在同一行)
字符串的contains();//括号里也要是字符串,不能是字符
class Solution {
public String[] findWords(String[] words) {
String s1 = "qwertyuiopQWERTYUIOP";
String s2 = "asdfghjklASDFGHJKL";
String s3 = "zxcvbnmZXCVBNM";
List<String>list=new ArrayList<>();
for(String word:words){
int n1 = 0,n2=0,n3=0;
int length=word.length();
for(int i=0;i<length;i++){
if(s1.contains(word.charAt(i)+"")){
n1++;
} else if(s2.contains(word.charAt(i)+"")){
n2++;
}else if(s3.contains(word.charAt(i)+"")){
n3++;
}
}
if(n1!=0&&n2==0&&n3==0){
list.add(word);
} else if(n1==0&&n2!=0&&n3==0){
list.add(word);
}else if(n1==0&&n2==0&&n3!=0){
list.add(word);
}
}
String []res=new String[list.size()];
int i=0;
for(String ans:list){
res[i++]=ans;
}
return res;
}
}
1984、学生分数的最小差值
给你一个 下标从 0 开始 的整数数组 nums
,其中 nums[i]
表示第 i
名学生的分数。另给你一个整数 k
。从数组中选出任意 k
名学生的分数,使这 k
个分数间 最高分 和 最低分 的 差值 达到 最小化 。返回可能的 最小差值 。
滑动窗口算法可以用以解决数组/字符串的子元素问题
子串/数组+最值 --> 滑动窗口
滑动窗口:可以看成数组中框起来的一个部分。在一些数组类题目中,我们可以用滑动窗口来观察可能的候选结果。当滑动窗口从数组的左边滑到了右边,我们就可以从所有的候选结果中找到最优的结果。
窗口的大小:1、固定大小
2、可变大小:根据题目的说明,来扩大右窗口,缩小左窗口
【算法】滑动窗口 - Curryxin - 博客园 (cnblogs.com)https://www.cnblogs.com/Curryxin/p/15131386.html
class Solution {
public int minimumDifference(int[] nums, int k) {
//滑动窗口的大小取决于k
Arrays.sort(nums);
//一定先排序好再差值计算:k=3取3名学生分数,计算差值,排序后只要算第一个和第三个的差值就行。
int min=Integer.MAX_VALUE;
for(int i=0;i+k-1<nums.length;i++){
int res=(nums[i+k-1]-nums[i]);
min=Math.min(min,res);
}
return min;
}
}