Open In App

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

Last Updated : 15 Nov, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

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;
}


Java




// Java program for above approach
import java.util.*;
 
public class Solution {
 
  // 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;
    for (int 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 generate next permutation of array
  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
      int t = nums[startIndex];
      nums[startIndex] = nums[endIndex];
      nums[endIndex] = t;
    }
 
    // 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) {
      int t = nums[start];
      nums[start] = nums[end];
      nums[end] = t;
    }
  }
 
  // 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
    System.out.println(KvisibleFromLeft(N, K));
  }
}
 
// This code is contributed by karandeep1234.


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.


Javascript




function swap(nums,  i, j) {
        let temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
  
function reverse(nums, start) {
        let i = start, j = nums.length - 1;
        while (i < j) {
            swap(nums, i, j);
            i++;
            j--;
        }
    }
// function to find next greater permutation
function nextPermutation(nums) {
        let i = nums.length - 2;
        while (i >= 0 && nums[i + 1] <= nums[i]) {
            i--;
        }
        let flag= false;
        if (i >= 0) {
            let j = nums.length - 1;
            while (nums[j] <= nums[i]) {
                j--;
            }
            swap(nums, i, j);
            flag = true;
        }
        reverse(nums,i+1);
       return flag;
    }
 
// Function to calculate the number
// of bars that are visible from
// the left for a particular arrangement
function noOfbarsVisibleFromLeft(v)
{
    let last = 0, ans = 0;
    for (let i=0;i< v.length;i++)
 
        // If current element is greater
// than the last greater element,
// it is visible
        if (last < v[i]) {
            ans++;
            last = v[i];
        }
    return ans;
}
 
// Function to calculate the number
// of rearrangements where
// K bars are visible from the left
function KvisibleFromLeft(N, K)
{
    // Vector to store current permutation
    let v=[];
    for (let i = 0; i < N; i++)
        v.push(i + 1);
    let ans = 0;
 
    // Check for all permutations
    do {
        // If current permutation meets
// the conditions, increment answer
        if (noOfbarsVisibleFromLeft(v) == K)
             ans++;
    } while (nextPermutation(v)==true);
 
    return ans;
}
 
// Driver code
 
    // Input
    let N = 5, K = 2;
 
    // Function call
    console.log( KvisibleFromLeft(N, K) );
 
// This code is contributed by garg28harsh.


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)

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads