题目496:
You are given two arrays (without duplicates) nums1
and nums2
where nums1
’s
elements are subset of nums2
. Find all the next greater numbers for nums1
's
elements in the corresponding places of nums2
.
The Next Greater Number of a number x in nums1
is
the first greater number to its right in nums2
. If it does not exist, output
-1 for this number.
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. Output: [-1,3,-1] Explanation: For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. For number 1 in the first array, the next greater number for it in the second array is 3. For number 2 in the first array, there is no next greater number for it in the second array, so output -1.
Example 2:
Input: nums1 = [2,4], nums2 = [1,2,3,4]. Output: [3,-1] Explanation: For number 2 in the first array, the next greater number for it in the second array is 3. For number 4 in the first array, there is no next greater number for it in the second array, so output -1.
Note:
- All elements in
nums1
andnums2
are unique. - The length of both
nums1
andnums2
would not exceed 1000.
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
//给定两个数组,其中nums1是nums2的子集(无重复)。请分别找出nums1中的元素在nums2中后面比该元素大的第一个元素
//若在nums2中后面不存在这样的更大的元素,返回-1代替。
//思路:使用数组实现,将以nums2的元素为下标存入对应的位置
int [] res=new int[nums1.length];
//初始化数组
Arrays.fill(res,-1);
//确定下标数组的范围
int maxNum=Integer.MIN_VALUE;
int minNum=Integer.MAX_VALUE;
for(int i=0;i<nums2.length;i++){
maxNum=Math.max(maxNum,nums2[i]);
minNum=Math.min(minNum,nums2[i]);
}
//创建对应的下标数组,为了方便直接从对应元素后面查找
int [] index=new int[maxNum-minNum+1];
for(int i=0;i<nums2.length;i++){
index[nums2[i]-minNum]=i;
}
//查找元素
for(int i=0;i<nums1.length;i++){
for(int j=index[nums1[i]-minNum];j<nums2.length;j++){
if(nums2[j]>nums1[i]){
res[i]=nums2[j];
break;
}
}
}
return res;
}
}
题目503:
Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number.
Example 1:
Input: [1,2,1] Output: [2,-1,2] Explanation: The first 1's next greater number is 2;
The number 2 can't find next greater number;
The second 1's next greater number needs to search circularly, which is also 2.
Note: The length of given array won't exceed 10000.
分析(原创-易理解):class Solution {
public int[] nextGreaterElements(int[] nums) {
//类似Next Greater Element的原理,只是这里首尾是相连的,当判断末尾时,需要从头开始继续判断。
//直到找到满足条件位为止,否则返回-1。(注意:存在相同元素)
//思路:类似498的解法,求出每个元素的的下标,如果相同的元素,直接更新下标。
//Hint:每个元素寻找的长度为n-1(前面n-1个和后面n-i+1个),利用mod回到原点继续遍历
int [] res=new int[nums.length];
if(nums.length==0) return res;
Arrays.fill(res,-1);
//遍历查找
for(int i=0;i<nums.length;i++){
for(int j=i+1;j<nums.length+i;j++){
//求mod运算
if(nums[j%nums.length]>nums[i]){
res[i]=nums[j%nums.length];
break;
}
}
}
return res;
}
}
分析2(参考答案-推荐):
class Solution {
public int[] nextGreaterElements(int[] nums) {
//类似Next Greater Element的原理,只是这里首尾是相连的,当判断末尾时,需要从头开始继续判断。
//直到找到满足条件位为止,否则返回-1。(注意:存在相同元素)
//思路:类似498的解法,使用一个栈来记录,找到比前面元素n大的话,直至不满足的条件。就在数组中n下标的赋值比其大的数
//两轮比较,数组中的每个数都能找到比其大的。
int len=nums.length;
int [] next=new int[len];
Arrays.fill(next,-1);
Stack<Integer> stack = new Stack<>();
//轮询两次,来表示一个完整的环
for(int i=0;i<len*2;i++){
int num=nums[i%len];
//取栈定元素进行比较
while(!stack.empty()&&nums[stack.peek()]<num){
//找到比其大的,重新赋值
next[stack.pop()]=num;
}
if(i<len){
//将下标存入
stack.push(i);
}
}
return next;
}
}
题目556:
Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly the same digits existing in the integer nand is greater in value than n. If no such positive 32-bit integer exists, you need to return -1.
Example 1:
Input: 12 Output: 21
Example 2:
Input: 21 Output: -1
分析556(原创):
class Solution {
public static int nextGreaterElement(int n) {
//给定一个正整数,你需要返回由其的数字组成的,且比其大的最小元素,若这样的数不存在,则返回-1
//思路:对该数字进行切分,将其各个位置的数放入一个数字,结合前面503和498的解法,来求解比其大的Next Great Element
//注意:不能使用枚举的方法将所有子集列出,必定TLM
//分三种情况:1:升序。则只需要将最后面两个数字交换即可
// 2:降序。则没有满足条件的,返回-1
// 3:不符合上述两者的无序情况(从右边开始查找第一个不满足比后面一个前面一个大的数,
// 之后将该数和它右边比其大的数交换,最后将后半段排序即可)
int temp=n;
int len=0;
while(temp>0){
temp/=10;
len++;
}
//创建数组
int [] res=new int[len];
int newTemp=n;
//将各个元素放入数组(正序放入)
while(newTemp>0){
res[--len]=newTemp%10;
newTemp/=10;
}
//判断所属情况
int i;
for(i=res.length-1;i>0;i--){
if(res[i]>res[i-1])
break;
}
if(i==0){
//说明为降序
return -1;
}
//找到恰好满足比当前位置大的数
int x=res[i-1],minIndex=i;
for(int j=i+1;j<res.length;j++){
if(res[j]>x&&res[j]<=res[minIndex]){
minIndex=j;
}
}
//交换位置
swap(res,i-1,minIndex);
//右半部分排序
Arrays.sort(res,i,res.length);
//转成结果
return transform(res)>Integer.MAX_VALUE?-1:(int)transform(res);
}
//交换数据
public static int[] swap(int [] nums,int n,int m){
int temp=nums[m];
nums[m]=nums[n];
nums[n] = temp;
return nums;
}
//将数组转成数字(Integer的范围)
public static long transform(int [] nums){
long sum=0;
for(int i=0;i<nums.length;i++){
sum=sum*10+nums[i];
}
return sum;
}
}