496. Next Greater Element I
暴力解法比较简单,也可以使用单调栈可以解决这一问题,精髓之处:栈中存储的值要始终比当前值大,否则就弹栈知道栈顶元素大于当前值,而这个栈顶元素就是比当前元素大的第一个值。然后再将当前值压栈。
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
HashMap<Integer,Integer> map=new HashMap<>();
Stack<Integer> stack=new Stack<>();
for(int i=nums2.length-1;i>=0;i--){
while(!stack.isEmpty() && nums2[i]>=stack.peek()){
stack.pop();
}
if(!stack.isEmpty())
map.put(nums2[i],stack.peek());
stack.push(nums2[i]);
}
int[] ret=new int[nums1.length];
for(int i=0;i<nums1.length;i++){
ret[i]=map.getOrDefault(nums1[i],-1);
}
return ret;
}
}
503. Next Greater Element II
解法一:使用数组模拟循环队列,与约瑟夫环问题的模拟类似,暴力解法。内部循环的的终止条件:j%nums.length!=i
class Solution {
public int[] nextGreaterElements(int[] nums) {
int[] ans=new int[nums.length];
for(int i=0;i<nums.length;i++){
int j=i+1;
for(;j%nums.length!=i;j++){
if(nums[j%nums.length]>nums[i])
{
ans[i]=nums[j%nums.length];
break;
}
}
if(j%nums.length==i)
ans[i]=-1;
}
return ans;
}
}
解法二:单调栈,这里使用两倍的数组长度来模拟循环队列。
class Solution {
public int[] nextGreaterElements(int[] nums) {
int n=2*nums.length;
int[] ans=new int[nums.length];
Arrays.fill(ans,-1);
Stack<Integer> stack=new Stack<>();
for(int i=0;i<n;i++){
while(!stack.isEmpty() && nums[stack.peek()]<nums[i%nums.length])
{
ans[stack.pop()]=nums[i%nums.length];
}
stack.push(i%nums.length);
}
return ans;
}
}
556. Next Greater Element III
这个问题看似复杂,实际上找几个例子就能够找到规律了。对于当前字符串表示的数字从尾部开始遍历,寻找第一个相邻上升对pair,然后将pair的第一个数字换成当前遍历过的最接近的比它较大的数字。然后将已经遍历的剩余数字排序即可。这个算法实现起来看起来比较丑陋,但是思路比较自然。
class Solution {
public int nextGreaterElement(int z) {
char[] str=String.valueOf(z).toCharArray();
int i=str.length-1;
ArrayList<Character> arr=new ArrayList<>();
for(;i>0;i--)
{
if(str[i-1]<str[i])
{
arr.add(str[i]);
int dx=9,index=arr.size()-1;
for(int n=0;n<arr.size();n++)
{
if(arr.get(n)-str[i-1]>0 && arr.get(n)-str[i-1]<dx){
dx=arr.get(n)-str[i-1];
index=n;
}
}
char tmp=arr.remove(index);
arr.add(str[i-1]);
str[i-1]=tmp;
break;
}
arr.add(str[i]);
}
if(i==0)
return -1;
StringBuilder sb=new StringBuilder();
for(int j=0;j<i;j++)
sb.append(str[j]);
Collections.sort(arr);
for(int j=0;j<arr.size();j++)
sb.append(arr.get(j));
long ret=Long.valueOf(sb.toString());
return ret<=Integer.MAX_VALUE?(int)ret:-1;
}
}
class Solution {
public String removeDuplicateLetters(String s) {
char[] count=new char[26];
boolean[] visited=new boolean[26];
for(char c:s.toCharArray())
count[c-'a']++;
Deque<Character> deque=new LinkedList<Character>();
for(char c:s.toCharArray())
{
count[c-'a']--;
if(visited[c-'a'])
continue;
while(deque.size()!=0 && deque.peekLast().charValue()>c && count[deque.peekLast()-'a']!=0)
{
visited[deque.pollLast()-'a']=false;
}
deque.add(c);
visited[c-'a']=true;
}
StringBuilder sb=new StringBuilder();
while(deque.size()!=0)
sb.append(deque.pollFirst());
return sb.toString();
}
}