第一题:寻找子集合中每个元素在原集合中右边第一个比它大的数。

想到了用哈希表存这个数的位置,但是没有想到可以直接用哈希表存next great,用栈存还没找到的数,没遍历一个数就考察栈中的元素小,小的话,这个数就是栈中数的next great,栈中的数肯定是下大上小。

public int[] nextGreaterElement(int[] nums1, int[] nums2) {
/*
通过map建立当前元素和其next great的映射
在建立映射时,用栈记录还没有映射(就是还没有找到next great)的数,每新遍历一个数,就考察栈顶元素能不能映射,能就
建立映射,弹出栈顶,并继续考察新栈顶。不能建立后,压入该数。
一开始不明白,会不会有下边小,上边大的情况,如果有这种情况的话,下边的数是建立不了映射的,但是想了想是不可能出现的,
因为每当有大的数的时候,小的会被弹出,大的会压入,所以栈顶是最小的数。
*/
Stack<Integer> st = new Stack<>();
Map<Integer,Integer> map = new HashMap<>();
int[] res = new int[nums1.length];
for (int num :
nums2) {
while (!st.isEmpty() && st.peek() < num)
{
map.put(st.peek(),num);
st.pop();
}
st.push(num);
}
for (int i = 0; i < res.length; i++) {
res[i] = map.getOrDefault(nums1[i],-1);
}
return res;
}

第二题:和第一题的不同点是这次是求一个循环数列中各个元素的next,而且可能有重复

循环的解决方法是遍历两轮,每次下标对n取余,这样两轮的下标就相同了

重复的解决方法是stack记录下标,而不是记录数据,每次有了next,直接存到res的相应位置

最后的res就相当于一个哈希表

public int[] nextGreaterElements2(int[] nums) {
/*
相对第一题的改变时数组成了循环数组,遍历到最后一个数之后可以再从第一个数开始
自己想的方案是暴力解,两层for
看了答案,这种循环数组遍历,下标的问题是用取余的方法,第二遍第1个数,相当于n+1个数,n+1%n = 1,正好是第一个数
以后遇上循环数组,就遍历两倍长度,%n取余后,两次遍历的下标就一样了
*/
int l = nums.length;
int[] res = new int[l];
//有的找不到,直接初始化数组为-1
Arrays.fill(res,-1);
Stack<Integer> st = new Stack<>();
//循环数组,遍历两倍长度的数组,每次都取余,这样每个元素都可以把它前后的元素都遍历到,对于第二轮遍历下标不对应的解决方法是
//取余,对n取余,下表就对应了。时间复杂度O(2n)
//还要考虑这次有重复,所以不能记录数,要记录下标
for (int i = 0; i < 2*l; i++) {
int num = nums[i%l];
while (!st.isEmpty() && nums[st.peek()] < num)
{
res[st.peek()] = num;
st.pop();
}
//只在第一轮遍历时记录下标
if (i<l) st.push(i);
}
return res;
}

第三题:找全排列的下一个数,之前做过,但是没做出来,f**k

public int nextGreaterElement3(int n) {
/*
没做出来
策略是:如果从第K为到末尾是递减的,且第k位大于第K-1位(也就是递减序列最高位是k),那么就倒序排列递减序列,并且找到
比k-1为大的那个最小数,交换位置
之前做过一个题,找全排列的下一个数,和这个一模一样
*/
String str = n+"";
int l = str.length();
if (l == 1)
return -1;
//注意这里k的初始值不是0,是l-1。因为是倒着开始判断,如果没有判断到则k不会改变,递减数列应该是从l-1开始,也就是最后一个数
int k = l-1;
//处理成数列好操作,StringBuilder也可以
char[] ch = str.toCharArray();
//找到递减数列开始的地方
for (int i = l-2; i >=0; i--) {
if (ch[i] < ch[i+1])
{
k = i+1;
break;
}
}
//翻转递减数列,这里也可以转为字符串用string自带的翻转
for (int i = k; i < k+(l-k)/2; i++) {
char temp = ch[i];
ch[i] = ch[l-1-(i-k)];
ch[l-1-(i-k)] = temp;
}
//更换位置
for (int i = k; i < l; i++) {
if (ch[i] > ch[k-1])
{
char temp = ch[i];
ch[i] = ch[k-1];
ch[k-1] = temp;
break;
}
}
String res = new String(ch);
//判断是不是超过了int最大值
Long a = Long.parseLong(res);
if (a >Integer.MAX_VALUE)
return -1;
int b = Integer.parseInt(res);
//如果数没有改变说明这个数是全排列中最大的数,没有下一个,输出-1,要判断一下
if (b == n)
return -1;
return b;
}

[leetcode]Next Greater Element的更多相关文章

  1. LeetCode——Next Greater Element I

    LeetCode--Next Greater Element I Question You are given two arrays (without duplicates) nums1 and nu ...

  2. [LeetCode] Next Greater Element III 下一个较大的元素之三

    Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly th ...

  3. [LeetCode] Next Greater Element II 下一个较大的元素之二

    Given a circular array (the next element of the last element is the first element of the array), pri ...

  4. [LeetCode] Next Greater Element I 下一个较大的元素之一

    You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...

  5. LeetCode Next Greater Element III

    原题链接在这里:https://leetcode.com/problems/next-greater-element-iii/description/ 题目: Given a positive 32- ...

  6. LeetCode: Next Greater Element I

    stack和map用好就行 public class Solution { public int[] nextGreaterElement(int[] findNums, int[] nums) { ...

  7. [LeetCode] 496. Next Greater Element I 下一个较大的元素 I

    You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset of n ...

  8. [LeetCode] 503. Next Greater Element II 下一个较大的元素 II

    Given a circular array (the next element of the last element is the first element of the array), pri ...

  9. [LeetCode] 556. Next Greater Element III 下一个较大的元素 III

    Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly th ...

随机推荐

  1. TensorFlow安装方法:附带坑解决办法

    >>添加Anaconda 仓库的镜像 Anaconda 安装包可以到 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 下载. ...

  2. Django 的JsonResponse 与json

    json

  3. pycharm 2018.2.4过期-激活处理方式(Axure8.0版本到期)

    参考文章:https://blog.csdn.net/HALEN001/article/details/81137092 第一种方法亲测可以 大致步骤: 1.2018.8.15更新最新破解补丁Jetb ...

  4. swagger添加统一认证参数

    import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Co ...

  5. JAVA获取指定的类型的本机MAC地址

    前面我们运维小伙在部署的时候,发现在真实服务器获取不到mac地址或者获取不到指定类型的mac地址,写程序记录如下 import com.google.common.base.Strings; impo ...

  6. STL——容器(deque)deque 的删除 clear() erase()

    deque.clear(); //移除容器的所有数据 1 #include <iostream> 2 #include <deque> 3 4 using namespace ...

  7. 编译opencv4.5.0

    1. 环境vs2017或其它版本cmake-3.18设置环境变量OPENCV_TEST_DATA_PATH 值设置为 D:\sdk\vs2017\opencv-4.5.0\opencv_extra-4 ...

  8. 云图说 | 云上资源管控有神器!关于IAM,你想知道的都在这里!

    摘要:统一身份认证(Identity and Access Management,简称IAM)是华为云上帮助您安全控制华为云资源访问权限的基础服务.通过本期云图说,您可以初步了解IAM的基本功能. 从 ...

  9. Flink读写Redis(二)-flink-redis-connector代码学习

    源码结构 RedisSink package org.apache.flink.streaming.connectors.redis; import org.apache.flink.configur ...

  10. Java读取系统默认时区

    工作中,遇到一个Java读取默认时区的问题,后来看了openjdk的源码,大致整理一下过程 public class Test { public void test(){ TimeZone.getDe ...