使用最大元素到达所有数组元素所需的最小跳转
给定一个包含N个不同整数的数组arr[] ,任务是找到从最大元素到达所有数组元素所需的最小跳转次数,这样如果值为arr[i]的值大于arr[j]并且arr[j]的值大于第i个和第 j个元素之间的所有其他元素。
例子:
Input: arr[] = {1, 3, 6, 5}
Output: [2, 1, 0, 1]
Explanation:
Below are the jumps required to reach each platform:
- For the 1st platform, the jump from the 3rd platform to the 2nd platform, then jump to the 1st platform is required. Hence, a total of 2 jumps are required.
- For the 2nd platform, the jump from the 3rd platform directly to the 2nd platform is required. Hence, a total of 1 jump are required.
- For the 3rd platform, we are already on the 3rd platform. Hence, a total of 0 jumps are required.
- For the 4th platform, the jump from the 3rd platform directly to the 4th platform is required. Hence, a total of 1 jump are required.
Input: arr[] = {3, 5}
Output: [1, 0]
方法:给定的问题可以使用动态规划来解决,动态规划是基于观察到从最大元素到第i个元素的最小跳跃可能比左侧下一个更大元素所需的最小跳跃的最小值大 1 或对。因此,这个想法是预先计算较大元素的结果并使用它们来找到较小元素的答案。请按照以下步骤解决给定的问题:
- 对于每个数组元素arr[i]存储两个索引L和R ,分别表示映射中左侧和右侧的下一个更大元素的索引。
- 按降序对数组arr[]进行排序。
- 初始化一个向量,比如ans[] ,它存储所有数组元素的最小跳跃。
- 遍历数组arr[]并执行以下步骤:
- 如果当前数组元素是最大元素,则当前元素需要0次跳转。
- 使用地图中存储的值查找下一个较大元素到当前元素左右的距离。将距离分别存储在变量L和R中。
- 根据以下标准更新最小跳跃的值,例如M :
- 如果 L 至少为 0 且 R 小于 N,则 M 的值为 min(ans[L], ans[R]) + 1。
- 如果 L 小于 0 且 R 小于 N,则 M 的值为 ans[R] + 1。
- 如果 L 至少为 0 且 R 至少为 N,则 M 的值为 ans[L] + 1。
- 将当前索引的最小跳跃值更新为M的值。
- 完成上述步骤后,将数组ans[]打印为索引的结果跳转。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
#define ar array
// Function to find next greater element
// to left and right of current element
ar expand(int idx, vector& A)
{
// Starting l and r from previous
// and the next element of the
// current element
int l = idx - 1;
int r = idx + 1;
// FInd the next greater element
// to the left
while (l >= 0) {
if ((int)(A[idx]) > A[l]) {
--l;
}
else {
break;
}
}
if (l < 0 || l == idx) {
l = -2;
}
// Find the next greater element
// to the right
while (r < (int)(A.size())) {
if ((int)A[idx] > A[r]) {
++r;
}
else {
break;
}
}
if (r >= (int)(A.size()) || r == idx) {
r = -2;
}
// Return l and r in the form of
// array of size 2
return { l, r };
}
// Function to find the minimum jumps
// required to reach to all elements from
// the largest element
vector minJumps(int N, vector& A)
{
vector ans(N, 0);
// Stores the mapping from index
// to the element in array A[]
map > mp;
map iToA;
map AToi;
// Stores largest array element
int big = A[0];
// Find the two indices l, r such
// that A[l] > A[i] < A[r] and
// l());
for (int i = 0; i < A.size(); ++i) {
// Stores the resultant minimum
// jumps required
int m;
// Check if the current element
// is largest or not
if (A[i] == big) {
int cur = AToi[A[i]];
ans[cur] = 0;
continue;
}
// Find the answer to the
// current element
int cur = AToi[A[i]];
int l = mp[cur][0];
int r = mp[cur][1];
if (l >= 0 && r < N) {
m = min(ans[l], ans[r]) + 1;
}
else if (l < 0 && r < N) {
m = ans[r] + 1;
}
else if (l >= 0 && r >= N) {
m = ans[l] + 1;
}
// Update the resultant minimum
// jumps for the current element
ans[cur] = m;
}
// Return the result
return ans;
}
// Driver Code
int main()
{
vector arr = { 5, 1, 3, 4, 7 };
int N = arr.size();
vector out = minJumps(N, arr);
// Print the result
for (auto& it : out)
cout << it << ' ';
return 0;
}
Python3
# Python program for the above approach
# Function to find next greater element
# to left and right of current element
def expand(idx, A):
# Starting l and r from previous
# and the next element of the
# current element
l = idx - 1
r = idx + 1
# FInd the next greater element
# to the left
while (l >= 0):
if (A[idx] > A[l]):
l -= 1
else:
break
if (l < 0 or l == idx):
l = -2
# Find the next greater element
# to the right
while (r < len(A)):
if (A[idx] > A[r]):
r += 1
else:
break
if (r >= len(A) or r == idx):
r = -2
# Return l and r in the form of
# array of size 2
return [l, r]
# Function to find the minimum jumps
# required to reach to all elements from
# the largest element
def minJumps(N, A):
ans = [0 for i in range(N)]
# Stores the mapping from index
# to the element in array A[]
mp = {}
iToA = {}
AToi = {}
# Stores largest array element
big = A[0]
# Find the two indices l, r such
# that A[l] > A[i] < A[r] and
# l= 0 and r < N):
m = min(ans[l], ans[r]) + 1
elif (l < 0 and r < N):
m = ans[r] + 1
elif (l >= 0 and r >= N):
m = ans[l] + 1
# Update the resultant minimum
# jumps for the current element
ans[cur] = m
# Return the result
return ans
# Driver Code
arr = [5, 1, 3, 4, 7]
N = len(arr)
out = minJumps(N, arr)
# Print the result
for it in out:
print(it, end=" ")
# This code is contributed by saurabh_jaiswal.
Javascript
输出:
1 2 2 1 0
时间复杂度: O(N 2 )
辅助空间: O(N)