Skip to content
Related Articles

Related Articles

Number of ways such that only K bars are visible from the left

View Discussion
Improve Article
Save Article
  • Difficulty Level : Hard
  • Last Updated : 03 Aug, 2022
View Discussion
Improve Article
Save Article

Given a number K, and N bars of height from 1 to N, the task is to find the number of ways to arrange the N bars such that only K bars are visible from the left.

Examples

Input: N=4, K=3
Output:
6
Explanation: The 6 permutations where only 3 bars are visible from the left are:

  • 1 2 4 3
  • 1 3 2 4
  • 1 3 4 2
  • 2 1 3 4
  • 2 3 1 4
  • 2 3 4 1

The Underlined bars are not visible.

Input: N=5, K=2
Output:
50

Naive Approach: The naive approach would be to check all permutations of 1 to N and check whether the number of bars visible from the left is K or not. 

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the number
// of bars that are visible from
// the left for a particular arrangement
int noOfbarsVisibleFromLeft(vector<int> v)
{
    int last = 0, ans = 0;
    for (auto u : v)
 
        // If current element is greater
// than the last greater element,
// it is visible
        if (last < u) {
            ans++;
            last = u;
        }
    return ans;
}
 
// Function to calculate the number
// of rearrangements where
// K bars are visible from the left
int KvisibleFromLeft(int N, int K)
{
    // Vector to store current permutation
    vector<int> v(N);
    for (int i = 0; i < N; i++)
        v[i] = i + 1;
    int ans = 0;
 
    // Check for all permutations
    do {
 
        // If current permutation meets
// the conditions, increment answer
        if (noOfbarsVisibleFromLeft(v) == K)
            ans++;
    } while (next_permutation(v.begin(), v.end()));
 
    return ans;
}
 
// Driver code
int main()
{
    // Input
    int N = 5, K = 2;
 
    // Function call
    cout << KvisibleFromLeft(N, K) << endl;
 
    return 0;
}


Python3




# Python3 program for the above approach
 
# Function to calculate the number
# of bars that are visible from
# the left for a particular arrangement
def noOfbarsVisibleFromLeft(v):
    last = 0
    ans = 0
 
    for u in v:
    # If current element is greater
    # than the last greater element,
    # it is visible
        if (last < u):
            ans += 1
            last = u
 
    return ans
 
def nextPermutation(nums):
    i = len(nums) - 2
    while i > -1:
        if nums[i] < nums[i + 1]:
            j = len(nums) - 1
            while j > i:
                if nums[j] > nums[i]:
                    break
                j -= 1
            nums[i], nums[j] = nums[j], nums[i]
            break
        i -= 1
    nums[i + 1:] = reversed(nums[i + 1:])
    return nums
   
# Function to calculate the number
# of rearrangements where
# K bars are visible from the left
def KvisibleFromLeft(N, K):
    # Vector to store current permutation
    v = [0]*(N)
    for i in range(N):
        v[i] = i + 1
    ans = 0
 
    temp = list(v)
 
    # Check for all permutations
    while True:
        # If current permutation meets
# the conditions, increment answer
        if (noOfbarsVisibleFromLeft(v) == K):
            ans += 1
        v = nextPermutation(v)
 
        if v == temp:
            break
 
    return ans
 
# Driver code
if __name__ == '__main__':
    # Input
    N = 5
    K = 2
 
    # Function call
    print (KvisibleFromLeft(N, K))
 
# This code is contributed by mohit kumar 29.


C#




// C# program to implement above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to calculate the number
    // of bars that are visible from
    // the left for a particular arrangement
    static int noOfbarsVisibleFromLeft(int[] v)
    {
        int last = 0, ans = 0;
        foreach (var u in v){
 
            // If current element is greater
            // than the last greater element,
            // it is visible
            if (last < u) {
                ans++;
                last = u;
            }
        }
        return ans;
    }
 
    // Function to generate next permutation of array
    public static void NextPermutation(int[] nums) {
        // Starting from the end, look for the first index that is not in descending order
        var startIndex = nums.Length - 2;
  
        while (startIndex >= 0) {
            // Find first decreasing element
            if (nums[startIndex] < nums[startIndex + 1]) {
                break;
            }
            --startIndex;
        }
  
        if (startIndex >= 0) {
            // Starting from the end, look for the first element greater than the start index
            int endIndex = nums.Length - 1;
  
            while (endIndex > startIndex) {
                // Find first greater element
                if (nums[endIndex] > nums[startIndex]) {
                    break;
                }
                --endIndex;
            }
  
            // Swap first and last elements
            Swap(ref nums[startIndex], ref nums[endIndex]);
        }
  
        // Reverse the array
        Reverse(nums, startIndex + 1);
    }
  
    static void Reverse(int[] nums, int startIndex) {
        for (int start = startIndex, end = nums.Length - 1; start < end; ++start, --end) {
            Swap(ref nums[start], ref nums[end]);
        }
    }
  
    static void Swap(ref int a, ref int b) {
        var tmp = a;
        a = b;
        b = tmp;
    }
 
    // Function to calculate the number
    // of rearrangements where
    // K bars are visible from the left
    static int KvisibleFromLeft(int N, int K)
    {
        // Vector to store current permutation
        int[] v = new int[N];
        for (int i = 0 ; i < N ; i++){
            v[i] = i + 1;
        }
        int ans = 0;
 
        int count = 1;
        for(int i = 1 ; i <= N ; i++){
            count *= i;
        }
 
        // Check for all permutations
        for(int i = 0 ; i < count ; i++){
            if (noOfbarsVisibleFromLeft(v) == K){
                ans++;
            }
            NextPermutation(v);
        }
 
        return ans;
    }
 
 
    // Driver Code
    public static void Main(string[] args){
         
        // Input
        int N = 5, K = 2;
 
        // Function call
        Console.Write(KvisibleFromLeft(N, K) + "\n");
 
    }
}
 
// This code is contributed by subhamgoyal2014.


Output

50

Time Complexity: O(N!)
Auxiliary Space: O(N)

Efficient Approach: The efficient approach would be to use recursion. Follow the steps below to solve the problem: 

  • Create a recursive function KvisibleFromLeft() that takes N and K as input parameters and does the following:
    • Base cases:
      • If N is equal to K, there is one way to arrange the bars, which is in ascending order. So, return 1.
      • If K==1, there are (N-1)! ways to arrange the bars, as the longest bar is placed in the first position and the remaining N-1 bars can be placed anywhere on the remaining N-1 positions. So, return (N-1)!.
    • For the recursion, there are two cases:
      • The smallest bar can be placed at the first position, then, among the remaining N-1 bars, only K-1 bars need to be visible. Thus, the answer would be the same as the number of ways to arrange N-1 bars such that K-1 bars are visible. This case, thus, recursively calls KvisibleFromLeft(N-1, K-1).
      • The smallest bar can be placed at any of the N-1 positions, other than the first. This would hide the smallest bar, and thus, the answer would be the same as the number of ways to arrange N-1 bars such that K bars are visible. Thus, this case recursively calls (N-1)*KvisibleFromLeft(N-1,K).

Below is the implementation of the above approach: 

C++




// C++ implementation for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate the number of permutations of
// N, where only K bars are visible from the left.
int KvisibleFromLeft(int N, int K)
{
 
    // Only ascending order is possible
    if (N == K)
        return 1;
 
    // N is placed at the first position
    // The nest N-1 are arranged in (N-1)! ways
    if (K == 1) {
        int ans = 1;
        for (int i = 1; i < N; i++)
            ans *= i;
        return ans;
    }
 
    // Recursing
    return KvisibleFromLeft(N - 1, K - 1)
           + (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
int main()
{
    // Input
    int N = 5, K = 2;
 
    // Function call
    cout << KvisibleFromLeft(N, K) << endl;
    return 0;
}


Java




// Java program for the above approach
class GFG{
 
// Function to calculate the number of
// permutations of N, where only K bars
// are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
     
    // Only ascending order is possible
    if (N == K)
        return 1;
 
    // N is placed at the first position
    // The nest N-1 are arranged in (N-1)! ways
    if (K == 1)
    {
        int ans = 1;
        for(int i = 1; i < N; i++)
            ans *= i;
             
        return ans;
    }
 
    // Recursing
    return KvisibleFromLeft(N - 1, K - 1) +
        (N - 1) * KvisibleFromLeft(N - 1, K);
}
 
// Driver code
public static void main(String[] args)
{
     
    // Input
    int N = 5, K = 2;
 
    // Function call
    System.out.println(KvisibleFromLeft(N, K));
}
}
 
// This code is contributed by abhinavjain194


Python3




# Python 3 implementation for the above approach
 
# Function to calculate the number of permutations of
# N, where only K bars are visible from the left.
def KvisibleFromLeft(N, K):
   
    # Only ascending order is possible
    if (N == K):
        return 1
 
    # N is placed at the first position
    # The nest N-1 are arranged in (N-1)! ways
    if (K == 1):
        ans = 1
        for i in range(1, N, 1):
            ans *= i
        return ans
 
    # Recursing
    return KvisibleFromLeft(N - 1, K - 1) + (N - 1) * KvisibleFromLeft(N - 1, K)
 
# Driver code
if __name__ == '__main__':
   
    # Input
    N = 5
    K = 2
 
    # Function call
    print(KvisibleFromLeft(N, K))
     
    # This code is contributed by ipg2016107.


C#




// C# program for the above approach
using System;
 
class GFG
{
 
// Function to calculate the number of
// permutations of N, where only K bars
// are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
     
    // Only ascending order is possible
    if (N == K)
        return 1;
 
    // N is placed at the first position
    // The nest N-1 are arranged in (N-1)! ways
    if (K == 1)
    {
        int ans = 1;
        for(int i = 1; i < N; i++)
            ans *= i;
             
        return ans;
    }
 
    // Recursing
    return KvisibleFromLeft(N - 1, K - 1) +
        (N - 1) * KvisibleFromLeft(N - 1, K);
}
 
// Driver code
public static void Main(String[] args)
{
     
    // Input
    int N = 5, K = 2;
 
    // Function call
    Console.Write(KvisibleFromLeft(N, K));
}
}
 
// This code is contributed by shivanisinghss2110


Javascript




<script>
// Javascript implementation for the above approach
 
 
// Function to calculate the number of permutations of
// N, where only K bars are visible from the left.
function KvisibleFromLeft(N, K) {
 
    // Only ascending order is possible
    if (N == K)
        return 1;
 
    // N is placed at the first position
    // The nest N-1 are arranged in (N-1)! ways
    if (K == 1) {
        let ans = 1;
        for (let i = 1; i < N; i++)
            ans *= i;
        return ans;
    }
 
    // Recursing
    return KvisibleFromLeft(N - 1, K - 1)
        + (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
 
// Input
let N = 5, K = 2;
 
// Function call
document.write(KvisibleFromLeft(N, K) + "<br>");
 
// This code is contributed by gfgking.
</script>


Output

50

Time Complexity: O(2N)
Auxiliary Space: O(1)

Efficient Approach: The above recursion can be memoized and thus, dynamic programming can be used as there are optimal substructures.

Below is the implementation of the above approach: 

C++




// C++ implementation for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// dp array
int dp[1005][1005];
 
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
int KvisibleFromLeft(int N, int K)
{
    // If subproblem has already
// been calculated, return
    if (dp[N][K] != -1)
        return dp[N][K];
 
    // Only ascending order is possible
    if (N == K)
        return dp[N][K] = 1;
 
    // N is placed at the first position
    // The nest N-1 are arranged in (N-1)! ways
    if (K == 1) {
        int ans = 1;
        for (int i = 1; i < N; i++)
            ans *= i;
        return dp[N][K] = ans;
    }
 
    // Recursing
    return dp[N][K]
           = KvisibleFromLeft(N - 1, K - 1)
             + (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
int main()
{
    // Input
    int N = 5, K = 2;
 
    // Initialize dp array
    memset(dp, -1, sizeof(dp));
 
    // Function call
    cout << KvisibleFromLeft(N, K) << endl;
    return 0;
}


Java




// Java implementation for the above approach
import java.util.*;
 
class GFG{
 
// dp array
static int [][]dp = new int[1005][1005];
 
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
    // If subproblem has already
// been calculated, return
    if (dp[N][K] != -1)
        return dp[N][K];
 
    // Only ascending order is possible
    if (N == K)
        return dp[N][K] = 1;
 
    // N is placed at the first position
    // The nest N-1 are arranged in (N-1)! ways
    if (K == 1) {
        int ans = 1;
        for (int i = 1; i < N; i++)
            ans *= i;
        return dp[N][K] = ans;
    }
 
    // Recursing
    return dp[N][K]
           = KvisibleFromLeft(N - 1, K - 1)
             + (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void main(String[] args)
{
    // Input
    int N = 5, K = 2;
 
    // Initialize dp array
    for(int i = 0; i < 1005; i++)
  {
    for (int j = 0; j < 1005; j++)
    {
      dp[i][j] = -1;
    }
  }
  
    // Function call
    System.out.print( KvisibleFromLeft(N, K));
}
}
 
// This code is contributed by shivanisinghss2110


Python3




# Python3 implementation for the above approach
 
# dp array
dp = [[0 for i in range(1005)] for j in range(1005)]
  
# Function to calculate the number
# of permutations of N, where
# only K bars are visible from the left.
def KvisibleFromLeft(N, K):
   
    # If subproblem has already
    # been calculated, return
    if (dp[N][K] != -1):
        return dp[N][K]
  
    # Only ascending order is possible
    if (N == K):
        dp[N][K] = 1
        return dp[N][K]
  
    # N is placed at the first position
    # The nest N-1 are arranged in (N-1)! ways
    if (K == 1):
        ans = 1
        for i in range(1, N):
            ans *= i
        dp[N][K] = ans
        return dp[N][K]
  
    # Recursing
    dp[N][K] = KvisibleFromLeft(N - 1, K - 1) + (N - 1) * KvisibleFromLeft(N - 1, K)
    return dp[N][K]
 
# Input
N, K = 5, 2
 
# Initialize dp array
for i in range(1005):
    for j in range(1005):
        dp[i][j] = -1
 
# Function call
print( KvisibleFromLeft(N, K))
 
# This code is contributed by divyeshrabadiya07.


C#




// C# implementation for the above approach
using System;
 
public class GFG{
 
// dp array
static int [,]dp = new int[1005, 1005];
 
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
static int KvisibleFromLeft(int N, int K)
{
    // If subproblem has already
// been calculated, return
    if (dp[N ,K] != -1)
        return dp[N,K];
 
    // Only ascending order is possible
    if (N == K)
        return dp[N,K] = 1;
 
    // N is placed at the first position
    // The nest N-1 are arranged in (N-1)! ways
    if (K == 1) {
        int ans = 1;
        for (int i = 1; i < N; i++)
            ans *= i;
        return dp[N,K] = ans;
    }
 
    // Recursing
    return dp[N,K]
           = KvisibleFromLeft(N - 1, K - 1)
             + (N - 1) * KvisibleFromLeft(N - 1, K);
}
// Driver code
public static void Main(String[] args)
{
    // Input
    int N = 5, K = 2;
 
    // Initialize dp array
    for(int i = 0; i < 1005; i++)
  {
    for (int j = 0; j < 1005; j++)
    {
      dp[i, j] = -1;
    }
  }
  
    // Function call
    Console.Write( KvisibleFromLeft(N, K));
}
}
 
// This code is contributed by shivanisinghss2110


Javascript




<script>
 
// Javascript implementation for
// the above approach
 
// dp array
let dp = new Array(1005).fill(0).map(
   () => new Array(1005).fill(-1));
 
// Function to calculate the number
// of permutations of N, where
// only K bars are visible from the left.
function KvisibleFromLeft(N, K)
{
     
    // If subproblem has already
    // been calculated, return
    if (dp[N][K] != -1)
        return dp[N][K];
 
    // Only ascending order is possible
    if (N == K)
        return dp[N][K] = 1;
 
    // N is placed at the first position
    // The nest N-1 are arranged in (N-1)! ways
    if (K == 1)
    {
        let ans = 1;
         
        for(let i = 1; i < N; i++)
            ans *= i;
             
        return dp[N][K] = ans;
    }
 
    // Recursing
    return dp[N][K] = KvisibleFromLeft(N - 1, K - 1) +
            (N - 1) * KvisibleFromLeft(N - 1, K);
}
 
// Driver code
 
// Input
let N = 5, K = 2;
 
// Function call
document.write(KvisibleFromLeft(N, K) + "<br>")
 
// This code is contributed by _saurabh_jaiswal
 
</script>


Output

50

Time Complexity: O(NK)
Auxiliary Space: O(NK)

 


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!