Equal Beauty CodeChef SnackDown 2021 Round 1A Question The beauty of an (non-empty) array of integers is defined as the difference between its largest and smallest element. For example, the beauty of the array [2,3,4,4,6] is 6−2=4. An array A is said to be good if it is possible to partition the elements of A into two non-empty arrays B1 and B2 such that B1 and B2 have the same beauty. Each element of array A should be in exactly one array: either in B1 or in B2. For example, the array [6,2,4,4,4] is good because its elements can be partitioned into two arrays B1=[6,4,4] and B2=[2,4], where both B1 and B2 have the same beauty (6−4=4−2=2). You are given an array A of length N. In one move you can: Select an index i (1≤i≤N) and either increase Ai by 1 or decrease Ai by 1. Find the minimum number of moves required to make the array A good. Input Format The first line of input contains a single integer T, denoting the number of test cases. The description of T test cases follow. Each ...
Next Greater Element I LeetCode Solution
Question
The next greater element of some element x
in an array is the first greater element that is to the right of x
in the same array.
You are given two distinct 0-indexed integer arrays nums1
and nums2
, where nums1
is a subset of nums2
.
For each 0 <= i < nums1.length
, find the index j
such that nums1[i] == nums2[j]
and determine the next greater element of nums2[j]
in nums2
. If there is no next greater element, then the answer for this query is -1
.
Return an array ans
of length nums1.length
such that ans[i]
is the next greater element as described above.
Example 1:
Input: nums1 = [4,1,2], nums2 = [1,3,4,2] Output: [-1,3,-1] Explanation: The next greater element for each value of nums1 is as follows: - 4 is underlined in nums2 = [1,3,4,2]. There is no next greater element, so the answer is -1. - 1 is underlined in nums2 = [1,3,4,2]. The next greater element is 3. - 2 is underlined in nums2 = [1,3,4,2]. There is no next greater element, so the answer is -1.
Example 2:
Input: nums1 = [2,4], nums2 = [1,2,3,4] Output: [3,-1] Explanation: The next greater element for each value of nums1 is as follows: - 2 is underlined in nums2 = [1,2,3,4]. The next greater element is 3. - 4 is underlined in nums2 = [1,2,3,4]. There is no next greater element, so the answer is -1.
Constraints:
1 <= nums1.length <= nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 104
- All integers in
nums1
andnums2
are unique. - All the integers of
nums1
also appear innums2
.
Explanation
This question is categorized in the easy section of LeetCode. This question can be solved in many approaches even due to the small constraints Brute Force approach will also work. Here we will explain the optimized approach using Maps, Stacks although brute force approach is also shown in the solutions given below. First we are discussing the approach used in python code. Sizes of both arrays are small enough, so we just can do brute-force solution in O(m * n), where n is size of nums2 and m is size of nums1. If we want to solve this problem in O(n) time, it is not so simple. The idea is to traverse nums2 and keep stack with decreasing order of elements. When we try to add element, if it is less than last element of stack, we just add it. If it is more than the last element, we extract it from stack and also put it inside dic: correspondence between numbers and its next greater element: we need it, because we have also nums1, which we need to traverse after. Next, when we traverse nums1 we can use function .get(num, -1), which will return answer for num if it is inside dictionary and -1 if it was not found. Now we are discussing a bit for the brute force approach The given could have been easily stated as given int arrays nums1 and nums2, for each number x in nums1, find the next greater number after x appearing in nums2. The algorithm below is generally basic and you can also solve it using a monotonically increasing stack. The first part of the algorithm is to convert nums2 into a map where it maps each number to an index. The second portion is to use a quadratic loop. The outer loop will iterate over all numbers in nums1 and the inner loop will iterate from where the number in nums1 is found in nums2 and find the next greater element. Once the next greater element is found, we can set result[i] = number in nums2 and move onto the next number in nums1. If not found, we just set result[i] = -1. Now discussing the optimized code for C++. Start traversing the nums2 array from last. Also create a stack & ans array. If current nums2[i] value is less than the stack top then simply push stack top to ans & then push nums2[i] to stack. If current nums2[i] value is greater than stack top then pop all values from stack until stack top is greater than nums2[i] or stack becomes empty. This is all we need to do, hope you understood the explanation. I recommend first to try the question yourself then if you are stuck you can approach the solutions given below in Java, C++, Python3, C#.
Program Code
Java
Brute Force with memorization
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
var indexByNum = new HashMap<Integer, Integer>();
for (var i = 0; i < nums2.length; i++)
indexByNum.put(nums2[i], i);
var memo = new HashMap<Integer, Integer>();
var result = new int[nums1.length];
for (var i = 0; i < nums1.length; i++)
result[i] = getNextGreater(nums1[i], nums2, indexByNum, memo);
return result;
}
private int getNextGreater(int query, int[] nums2, Map<Integer, Integer> indexByNum, Map<Integer, Integer> memo) {
if (memo.containsKey(query))
return memo.get(query);
for (var i = indexByNum.get(query); i < nums2.length; i++)
if (nums2[i] > query) {
memo.put(query, nums2[i]);
return nums2[i];
}
memo.put(query, -1);
return -1;
Optimized Code
class Solution {
public int[] nextGreaterElement(int[] nums1, int[] nums2) {
HashMap<Integer,Integer> hm = new HashMap<>();
int len2 = nums2.length;
int count = 0;
int [] ret = new int[nums1.length];
for (int i=0;i<nums2.length;i++){
hm.put(nums2[i],i);
}
for (int num : nums1){
int index = hm.get(num) +1;
ret[count] =-1;
while (index<len2){
if (nums2[index]>num){
ret[count] = nums2[index];
break;
}
index++;
}
count++;
}
return ret;
}
}
C++
class Solution {
public:
vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {
int n = nums2.size(),topp;
unordered_map<int,int>mp;
stack<int>s;
vector<int>ans(n);
for(int i=0;i<n;i++)
{
mp[nums2[i]]=i;
}
for(int i=n-1;i>=0;i--)
{
if(!s.empty())
{
topp = s.top();
while(nums2[i] > topp && !s.empty())
{
s.pop();
if(s.empty())
break;
topp = s.top();
}
if(s.empty())
{
ans[i]=-1;
s.push(nums2[i]);
}
else
{
topp = s.top();
ans[i]=topp;
s.push(nums2[i]);
}
}
else
{
ans[i]=-1;
s.push(nums2[i]);
}
}
int m = nums1.size();
vector<int>v;
for(int i=0;i<m;i++)
{
v.push_back(ans[mp[nums1[i]]]);
}
return v;
}
};
Python3
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
# Stores index of values in nums1
val_to_ind = {num:i for i, num in enumerate(nums1)}
# default answers
ans = [-1]*len(nums1)
n = len(nums2)
# first value in nums2 that is also in nums1
i = next(filter(lambda i: nums2[i] in val_to_ind, range(n)))
# Values for which we haven't found nextGreater, in descending order (stacked)
vals_left = [nums2[i]]
# Move forward in nums2, storing answers and unanswered values
for i in range(i+1, n):
# nums2[i] is next greater for smallest stored value
while vals_left and nums2[i]>vals_left[-1]:
# get smallest stored value, get its index in nums1, and update nextGreater at that index in ans
ans[val_to_ind.pop(vals_left.pop())] = nums2[i]
# is in nums1 (and is less than all values in vals_left because while loop exited, maintaining descending order in vals_left)
if nums2[i] in val_to_ind:
vals_left.append(nums2[i])
return ans
Another approach in Python3
class Solution:
def nextGreaterElement(self, nums1: List[int], nums2: List[int]) -> List[int]:
greater = {}
stack = []
for num in nums2:
while stack and stack[-1] < num:
greater[stack.pop()] = num
stack.append(num)
return [greater.get(num, -1) for num in nums1]
C#
public int[] NextGreaterElement(int[] nums1, int[] nums2) {
var dict = new Dictionary<int, int>();
var stack = new Stack<int>();
foreach (var n in nums2) {
while (stack.Any() && stack.Peek() < n)
dict[stack.Pop()] = n;
stack.Push(n);
}
return nums1.Select(x => dict.GetValueOrDefault(x, -1)).ToArray();
}
More Information About LeetCode Daily Challenge
LeetCode is a great coding platform which provides daily problems to solve and maintain a streak of coding. This platform helps in improvement of coding skills and attempting the daily challenge makes our practice of coding regular. With its bunch of questions available it is one of the best coding platforms where you can have self improvement. LeetCode also holds weekly and biweekly contests which is a great place to implement you knowledge and coding skills which you learnt through out the week by performing the daily challenge. It also provides badges if a coder solves all the daily problems of a month. For some lucky winners T-shirts are also given and that too for free. If you get the pro version you can get more from LeetCode like questions that are asked in interviews, detailed explanation of each chapter and each concept and much more. LeetCode challenges participants with a problem from our carefully curated collection of interview problems every 24 hours.
All users with all levels of coding background are welcome to join!
@PREMIUM USERS will have an extra carefully curated premium challenge weekly and earn extra LeetCoin rewards. The premium challenge will be available together with the first October challenge of the week and closed together with the November challenge of the week.
Starting from 2021, users who completed all Daily LeetCoding Challenge non-premium problems for the month (with or without using Time Travel Tickets) will win a badge to recognize their consistency! Your badges will be displayed on your profile page. Completing each non-premium daily challenge. (+10 LeetCoins)
Completing 25 to 30 non-premium daily challenges without using Time Travel Ticket will be eligible for an additional 25 LeetCoins. (Total = 275 to 325 LeetCoins)
Completing all 31 non-premium daily challenges without using Time Travel Ticket will be eligible for an additional 50 LeetCoins, plus a chance to win a secret prize ( Total = 385 LeetCoins + *Lucky Draw)!
Lucky Draw: Those who complete all 31 non-premium daily challenges will be automatically entered into a Lucky Draw, where LeetCode staff will randomly select 3 lucky participants to each receive one LeetCode Polo Shirt on top of their rewards! Do you have experience trying to keep a streak but failed because you missed one of the challenges?
Hoping you can travel back to the missed deadline to complete the challenge but that's not possible......or is it?
With the new Time Travel Ticket , it's possible! In order to time travel, you will need to redeem a Time Travel Ticket with your LeetCoins. You can redeem up to 3 tickets per month and the tickets are only usable through the end of the month in which they are redeemed but you can use the tickets to make up any invalid or late submission of the current year. To join, just start solving the daily problem on the calendar of the problem page. You can also find the daily problem listed on the top of the problem page. No registration is required. The daily problem will be updated on every 12 a.m. Coordinated Universal Time (UTC) and you will have 24 hours to solve that challenge. Thar's all you needed to know about Daily LeetCode Challenge.
Comments
Post a Comment