0% found this document useful (0 votes)
51 views

15) Trapping Rain Water

The document discusses multiple methods for solving the "Trapping Rain Water" problem in coding interviews using C++. It provides pseudocode implementations of 5 different approaches: two pointer, prefix sum, stack, two pass, and optimization of two pass method. For each method, it analyzes the time and space complexity and provides sample input/output.

Uploaded by

Irene Sultana
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views

15) Trapping Rain Water

The document discusses multiple methods for solving the "Trapping Rain Water" problem in coding interviews using C++. It provides pseudocode implementations of 5 different approaches: two pointer, prefix sum, stack, two pass, and optimization of two pass method. For each method, it analyzes the time and space complexity and provides sample input/output.

Uploaded by

Irene Sultana
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 51

15) Trapping Rain Water

// C++ implementation of the approach

#include<bits/stdc++.h>

using namespace std;

 // Function to return the maximum

// water that can be stored

int maxWater(int arr[], int n)

     // To store the maximum water

    // that can be stored

    int res = 0;

     

    // For every element of the array

    for (int i = 1; i < n-1; i++) {

         

        // Find the maximum element on its left

        int left = arr[i];

        for (int j=0; j<i; j++)

           left = max(left, arr[j]);

         
        // Find the maximum element on its right  

        int right = arr[i];

        for (int j=i+1; j<n; j++)

           right = max(right, arr[j]);

        

       // Update the maximum water   

       res = res + (min(left, right) - arr[i]);  

    }

    return res;

// Driver code

int main()

    int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};

    int n = sizeof(arr)/sizeof(arr[0]);

     

    cout << maxWater(arr, n);

     return 0;
}

Output
6
 Complexity Analysis: 
 Time Complexity: O(n2). 
There are two nested loops traversing the array, So time Complexity is
O(n2).
 Space Complexity: O(1). 
No extra space required.

Method 2: This is an efficient solution to the above problem.


// C++ program to find maximum amount of water that can
// be trapped within given set of bars.
#include <bits/stdc++.h>
using namespace std;

int findWater(int arr[], int n)


{
// left[i] contains height of tallest bar to the
// left of i'th bar including itself
int left[n];

// Right [i] contains height of tallest bar to


// the right of ith bar including itself
int right[n];
// Initialize result
int water = 0;

// Fill left array


left[0] = arr[0];
for (int i = 1; i < n; i++)
left[i] = max(left[i - 1], arr[i]);

// Fill right array


right[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--)
right[i] = max(right[i + 1], arr[i]);

// Calculate the accumulated water element by element


// consider the amount of water on i'th bar, the
// amount of water accumulated on this particular
// bar will be equal to min(left[i], right[i]) - arr[i] .
for (int i = 0; i < n; i++)
water += min(left[i], right[i]) - arr[i];

return water;
}

// Driver program
int main()
{
int arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum water that can be accumulated is "
<< findWater(arr, n);
return 0;
}
Output: Maximum water that can be accumulated is 6
 Complexity Analysis: 
 Time Complexity: O(n). 
Only one traversal of the array is needed, So time Complexity is O(n).
 Space Complexity: O(n). 
Two extra array is needed each of size n.

Space Optimization for above Solution:

// C++ program to find maximum amount of water that can


// be trapped within given set of bars.
// Space Complexity : O(1)

#include <iostream>
using namespace std;
int findWater(int arr[], int n)
{
// initialize output
int result = 0;

// maximum element on left and right


int left_max = 0, right_max = 0;

// indices to traverse the array


int lo = 0, hi = n - 1;

while (lo <= hi) {


if (arr[lo] < arr[hi]) {
if (arr[lo] > left_max)
// update max in left
left_max = arr[lo];
else
// water on curr element = max - curr
result += left_max - arr[lo];
lo++;
}
else {
if (arr[hi] > right_max)
// update right maximum
right_max = arr[hi];
else
result += right_max - arr[hi];
hi--;
}
}

return result;
}

int main()
{
int arr[] = { 0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Maximum water that can be accumulated is "
<< findWater(arr, n);
}
Output: 
Maximum water that can be accumulated is 6
 Complexity Analysis: 
 Time Complexity: O(n). 
Only one traversal of the array is needed.
 Auxiliary Space: O(1). 
As no extra space is required.
Method 3: Here another efficient solution has been shown.

// C++ implementation of the approach


#include<iostream>
using namespace std;

// Function to return the maximum


// water that can be stored
int maxWater(int arr[], int n)
{
int size = n - 1;

// Let the first element be stored as


// previous, we shall loop from index 1
int prev = arr[0];

// To store previous wall's index


int prev_index = 0;
int water = 0;

// To store the water until a larger wall


// is found, if there are no larger walls
// then delete temp value from water
int temp = 0;
for(int i = 1; i <= size; i++)
{

// If the current wall is taller than


// the previous wall then make current
// wall as the previous wall and its
// index as previous wall's index
// for the subsequent loops
if (arr[i] >= prev)
{
prev = arr[i];
prev_index = i;

// Because larger or same


// height wall is found
temp = 0;
}
else
{

// Since current wall is shorter than


// the previous, we subtract previous
// wall's height from the current wall's
// height and add it to the water
water += prev - arr[i];

// Store the same value in temp as well


// If we dont find any larger wall then
// we will subtract temp from water
temp += prev - arr[i];
}
}

// If the last wall was larger than or equal


// to the previous wall then prev_index would
// be equal to size of the array (last element)
// If we didn't find a wall greater than or equal
// to the previous wall from the left then
// prev_index must be less than the index
// of the last element
if(prev_index < size)
{

// Temp would've stored the water collected


// from previous largest wall till the end
// of array if no larger wall was found then
// it has excess water and remove that
// from water variable
water -= temp;

// We start from the end of the array,


// so previous should be assigned to
// the last element
prev = arr[size];

// Loop from the end of array up to the


// previous index which would contain
// the largest wall from the left
for(int i = size; i >= prev_index; i--)
{

// Right end wall will be definitely


// smaller than the 'previous index' wall
if(arr[i] >= prev)
{
prev = arr[i];
}
else
{
water += prev - arr[i];
}
}
}

// Return the maximum water


return water;
}

// Driver Code
int main()
{
int arr[] = { 0, 1, 0, 2, 1, 0,
1, 3, 2, 1, 2, 1 };
int n = sizeof(arr) / sizeof(arr[0]);

cout << maxWater(arr, n);


return 0;
}
Output
6
 Complexity Analysis: 
 Time Complexity: O(n). 
As only one traversal of the array is needed.
 Auxiliary Space: O(1). 
As no extra space is required.

Method 4 (Using Stack):

// C++ implementation of the approach


#include <bits/stdc++.h>
using namespace std;

// Function to return the maximum


// water that can be stored
int maxWater(int height[], int n)
{

// Stores the indices of the bars


stack <int> st;

// Stores the final result


int ans = 0;

// Loop through the each bar


for(int i = 0; i < n; i++)
{
// Remove bars from the stack
// until the condition holds
while ((!st.empty()) &&
(height[st.top()] < height[i]))
{

// Store the height of the top


// and pop it.
int pop_height = height[st.top()];
st.pop();

// If the stack does not have any


// bars or the the popped bar
// has no left boundary
if (st.empty())
break;

// Get the distance between the


// left and right boundary of
// popped bar
int distance = i - st.top() - 1;
// Calculate the min. height
int min_height = min(height[st.top()],
height[i]) -
pop_height;

ans += distance * min_height;


}

// If the stack is either empty or


// height of the current bar is less than
// or equal to the top bar of stack
st.push(i);
}
return ans;
}

// Driver code
int main()
{

int arr[] = { 0, 1, 0, 2, 1, 0,
1, 3, 2, 1, 2, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << maxWater(arr, n);

return 0;
}
Output:
6
Time Complexity: O(n)
Auxiliary Space: O(n) 

Method 5 (Two Pointer Approach)

// C++ implementation of the approach


#include <iostream>
using namespace std;

int maxWater(int arr[], int n)


{

// indices to traverse the array


int left = 0;
int right = n-1;

// To store Left max and right max


// for two pointers left and right
int l_max = 0;
int r_max = 0;

// To store the total amount


// of rain water trapped
int result = 0;
while (left <= right)
{

// We need check for minimum of left


// and right max for each element
if(r_max <= l_max)
{

// Add the difference between


// current value and right max at index r
result += max(0, r_max-arr[right]);

// Update right max


r_max = max(r_max, arr[right]);

// Update right pointer


right -= 1;
}
else
{

// Add the difference between


// current value and left max at index l
result += max(0, l_max-arr[left]);

// Update left max


l_max = max(l_max, arr[left]);

// Update left pointer


left += 1;
}
}
return result;
}

// Driver code
int main() {
int arr[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
int n = sizeof(arr)/sizeof(arr[0]);
cout << maxWater(arr, n) << endl;
return 0;
}
Output :
6
Time Complexity: O(n)
Auxiliary Space: O(1) 
16) Pythagorean Triplets
Method 1 (Naive) 

// A C++ program that returns true if there is a Pythagorean


// Triplet in a given array.
#include <iostream>

using namespace std;

// Returns true if there is Pythagorean triplet in ar[0..n-1]


bool isTriplet(int ar[], int n)
{
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
// Calculate square of array elements
int x = ar[i] * ar[i], y = ar[j] * ar[j], z = ar[k] * ar[k];

if (x == y + z || y == x + z || z == x + y)
return true;
}
}
}

// If we reach here, no triplet found


return false;
}

/* Driver program to test above function */


int main()
{
int ar[] = { 3, 1, 4, 6, 5 };
int ar_size = sizeof(ar) / sizeof(ar[0]);
isTriplet(ar, ar_size) ? cout << "Yes" : cout << "No";
return 0;
}
Method 2 (Use Sorting) 

// A C++ program that returns true if there is a Pythagorean


// Triplet in a given array.
#include <algorithm>
#include <iostream>
using namespace std;

// Returns true if there is a triplet with following property


// A[i]*A[i] = A[j]*A[j] + A[k]*[k]
// Note that this function modifies given array
bool isTriplet(int arr[], int n)
{
// Square array elements
for (int i = 0; i < n; i++)
arr[i] = arr[i] * arr[i];

// Sort array elements


sort(arr, arr + n);

// Now fix one element one by one and find the other two
// elements
for (int i = n - 1; i >= 2; i--) {
// To find the other two elements, start two index
// variables from two corners of the array and move
// them toward each other
int l = 0; // index of the first element in arr[0..i-1]
int r = i - 1; // index of the last element in arr[0..i-1]
while (l < r) {
// A triplet found
if (arr[l] + arr[r] == arr[i])
return true;

// Else either move 'l' or 'r'


(arr[l] + arr[r] < arr[i]) ? l++ : r--;
}
}

// If we reach here, then no triplet found


return false;
}

/* Driver program to test above function */


int main()
{
int arr[] = { 3, 1, 4, 6, 5 };
int arr_size = sizeof(arr) / sizeof(arr[0]);
isTriplet(arr, arr_size) ? cout << "Yes" : cout << "No";
return 0;
}
Output:
Yes
Time complexity of this method is O(n2).

Method 3: (Using Hashing) 

#include <bits/stdc++.h>
using namespace std;

// Function to check if the


// Pythagorean triplet exists or not
bool checkTriplet(int arr[], int n)
{
int maximum = 0;

// Find the maximum element


for (int i = 0; i < n; i++) {
maximum = max(maximum, arr[i]);
}

// Hashing array
int hash[maximum + 1] = { 0 };

// Increase the count of array elements


// in hash table
for (int i = 0; i < n; i++)
hash[arr[i]]++;

// Iterate for all possible a


for (int i = 1; i < maximum + 1; i++) {

// If a is not there
if (hash[i] == 0)
continue;

// Iterate for all possible b


for (int j = 1; j < maximum + 1; j++) {

// If a and b are same and there is only one a


// or if there is no b in original array
if ((i == j && hash[i] == 1) || hash[j] == 0)
continue;

// Find c
int val = sqrt(i * i + j * j);

// If c^2 is not a perfect square


if ((val * val) != (i * i + j * j))
continue;

// If c exceeds the maximum value


if (val > maximum)
continue;

// If there exists c in the original array,


// we have the triplet
if (hash[val]) {
return true;
}
}
}
return false;
}
// Driver Code
int main()
{
int arr[] = { 3, 2, 4, 6, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
if (checkTriplet(arr, n))
cout << "Yes";
else
cout << "No";
}
Method -4:Using STL

#include <bits/stdc++.h>
using namespace std;

// Returns true if there is Pythagorean triplet in


// ar[0..n-1]
bool checkTriplet(int arr[], int n)
{
// initializing unordered map with key and value as
// integers
unordered_map<int, int> umap;

// Increase the count of array elements in unordered map


for (int i = 0; i < n; i++)
umap[arr[i]] = umap[arr[i]] + 1;

for (int i = 0; i < n - 1; i++)


{
for (int j = i + 1; j < n; j++)
{
// calculating the squares of two elements as
// integer and float
int p = sqrt(arr[i] * arr[i] + arr[j] * arr[j]);
float q
= sqrt(arr[i] * arr[i] + arr[j] * arr[j]);

// Condition is true if the value is same in


// integer and float and also the value is
// present in unordered map
if (p == q && umap[p] != 0)
return true;
}
}

// If we reach here, no triplet found


return false;
}

// Driver Code
int main()
{
int arr[] = { 3, 2, 4, 6, 5 };
int n = sizeof(arr) / sizeof(arr[0]);
if (checkTriplet(arr, n))
cout << "Yes";
else
cout << "No";
}
Output
Yes
Time Complexity:O(n2)

17) Chocolate Distribution Problem

// C++ program to solve chocolate distribution


// problem
#include <bits/stdc++.h>
using namespace std;

// arr[0..n-1] represents sizes of packets


// m is number of students.
// Returns minimum difference between maximum
// and minimum values of distribution.
int findMinDiff(int arr[], int n, int m)
{
// if there are no chocolates or number
// of students is 0
if (m == 0 || n == 0)
return 0;

// Sort the given packets


sort(arr, arr + n);

// Number of students cannot be more than


// number of packets
if (n < m)
return -1;
// Largest number of chocolates
int min_diff = INT_MAX;

// Find the subarray of size m such that


// difference between last (maximum in case
// of sorted) and first (minimum in case of
// sorted) elements of subarray is minimum.

for (int i = 0; i + m - 1 < n; i++) {


int diff = arr[i + m - 1] - arr[i];
if (diff < min_diff)
min_diff = diff;
}
return min_diff;
}

int main()
{
int arr[] = { 12, 4, 7, 9, 2, 23, 25, 41, 30,
40, 28, 42, 30, 44, 48, 43, 50 };
int m = 7; // Number of students
int n = sizeof(arr) / sizeof(arr[0]);
cout << "Minimum difference is "
<< findMinDiff(arr, n, m);
return 0;
}

18) Maximum profit by buying and selling a share at most twice


// C++ program to find maximum
// possible profit with at most
// two transactions
#include <bits/stdc++.h>
using namespace std;
// Returns maximum profit with
// two transactions on a given
// list of stock prices, price[0..n-1]
int maxProfit(int price[], int n)
{
// Create profit array and
// initialize it as 0
int* profit = new int[n];
for (int i = 0; i < n; i++)
profit[i] = 0;

/* Get the maximum profit with


only one transaction
allowed. After this loop,
profit[i] contains maximum
profit from price[i..n-1]
using at most one trans. */
int max_price = price[n - 1];
for (int i = n - 2; i >= 0; i--) {
// max_price has maximum
// of price[i..n-1]
if (price[i] > max_price)
max_price = price[i];

// we can get profit[i] by taking maximum of:


// a) previous maximum, i.e., profit[i+1]
// b) profit by buying at price[i] and selling at
// max_price
profit[i]
= max(profit[i + 1], max_price - price[i]);
}

/* Get the maximum profit with two transactions allowed


After this loop, profit[n-1] contains the result */
int min_price = price[0];
for (int i = 1; i < n; i++) {
// min_price is minimum price in price[0..i]
if (price[i] < min_price)
min_price = price[i];

// Maximum profit is maximum of:


// a) previous maximum, i.e., profit[i-1]
// b) (Buy, Sell) at (min_price, price[i]) and add
// profit of other trans. stored in profit[i]
profit[i] = max(profit[i - 1],
profit[i] + (price[i] - min_price));
}
int result = profit[n - 1];

delete[] profit; // To avoid memory leak


return result;
}

// Driver code
int main()
{
int price[] = { 2, 30, 15, 10, 8, 25, 80 };
int n = sizeof(price) / sizeof(price[0]);
cout << "Maximum Profit = " << maxProfit(price, n);
return 0;
}
Output
Maximum Profit = 100
The time complexity of the above solution is O(n). 
 Valley-Peak approach

#include <iostream>
using namespace std;

int main()
{
int price[] = { 2, 30, 15, 10, 8, 25, 80 };
int n = 7;

// adding array
int profit = 0;
// Initializing variable
// valley-peak approach
/*
80
/
30 /
/\ 25
/ 15 /
/ \ /
2 10 /
\/
8
*/
for (int i = 1; i < n; i++)
{

// traversing through array from (i+1)th


// position
int sub = price[i] - price[i - 1];
if (sub > 0)
profit += sub;
}

cout << "Maximum Profit=" << profit;


return 0;
}
Output
Maximum Profit=100
The time and space complexity is O(n) and O(1) respectively.
19)Find the element before which all the elements are smaller than it,
and after which all are greater
// C++ program to find the element which is greater than
// all left elements and smaller than all right elements.
#include <bits/stdc++.h>
using namespace std;

// Function to return the index of the element which is greater than


// all left elements and smaller than all right elements.
int findElement(int arr[], int n)
{
// leftMax[i] stores maximum of arr[0..i-1]
int leftMax[n];
leftMax[0] = INT_MIN;

// Fill leftMax[]1..n-1]
for (int i = 1; i < n; i++)
leftMax[i] = max(leftMax[i-1], arr[i-1]);

// Initialize minimum from right


int rightMin = INT_MAX;
// Traverse array from right
for (int i=n-1; i>=0; i--)
{
// Check if we found a required element
if (leftMax[i] < arr[i] && rightMin > arr[i])
return i;

// Update right minimum


rightMin = min(rightMin, arr[i]);
}

// If there was no element matching criteria


return -1;
}

// Driver program
int main()
{
int arr[] = {5, 1, 4, 3, 6, 8, 10, 7, 9};
int n = sizeof arr / sizeof arr[0];
cout << "Index of the element is " << findElement(arr, n);
return 0;
}
Output: 
Index of the element is 4
Time Complexity: O(n) 
Auxiliary Space: O(n)

Space Optimized Approach: 


// C++ program to find the element which is greater than
// all left elements and smaller than all right elements.
#include <bits/stdc++.h>
using namespace std;

int findElement(int a[], int n)


{
// Base case
if (n == 1 || n == 2) {
return -1;
}

// 1.element is the possible candidate for the solution


// of the problem.
// 2.idx is the index of the possible
// candidate.
// 3.maxx is the value which is maximum on the
// left side of the array.
// 4.bit tell whether the loop is
// terminated from the if condition or from the else
// condition when loop do not satisfied the condition.
// 5.check is the variable which tell whether the
// element is updated or not

int element = a[0], maxx = a[0], bit = -1, check = 0;


int idx = -1;

// The extreme two of the array can not be the solution


// Therefore iterate the loop from i = 1 to < n-1
for (int i = 1; i < (n - 1);) {

// here we find the possible candidate where Element


// with left side smaller and right side greater.
// when the if condition fail we check and update in
// else condition.

if (a[i] < maxx && i < (n - 1)) {


i++;
bit = 0;
}

// here we update the possible element if the


// element is greater than the maxx (maximum element
// so far). In while loop we sur-pass the value which
// is greater than the element
else {
if (a[i] >= maxx) {
element = a[i];
idx = i;
check = 1;
maxx = a[i];
}
if (check == 1) {
i++;
}
bit = 1;
while (a[i] >= element && i < (n - 1)) {
if (a[i] > maxx) {
maxx = a[i];
}
i++;
}
check = 0;
}
}

// checking for the last value and whether the loop is


// terminated from else or if block.

if (element <= a[n - 1] && bit == 1) {


return idx;
}
else {
return -1;
}
}

// Driver Code
int main()
{
int arr[] = { 5, 1, 4, 3, 6, 8, 10, 7, 9 };
int n = sizeof arr / sizeof arr[0];

// Function Call
cout << "Index of the element is "
<< findElement(arr, n);
return 0;
}
Output
Index of the element is 4
Time Complexity: O(n) 
Auxiliary Space: O(1)

20) Convert array into Zig-Zag fashion


// C++ program to sort an array in Zig-Zag form
#include <iostream>
using namespace std;
// Program for zig-zag conversion of array
void zigZag(int arr[], int n)
{
// Flag true indicates relation "<" is expected,
// else ">" is expected. The first expected relation
// is "<"
bool flag = true;

for (int i=0; i<=n-2; i++)


{
if (flag) /* "<" relation expected */
{
/* If we have a situation like A > B > C,
we get A > B < C by swapping B and C */
if (arr[i] > arr[i+1])
swap(arr[i], arr[i+1]);
}
else /* ">" relation expected */
{
/* If we have a situation like A < B < C,
we get A < C > B by swapping B and C */
if (arr[i] < arr[i+1])
swap(arr[i], arr[i+1]);
}
flag = !flag; /* flip flag */
}
}

// Driver program
int main()
{
int arr[] = {4, 3, 7, 8, 6, 2, 1};
int n = sizeof(arr)/sizeof(arr[0]);
zigZag(arr, n);
for (int i=0; i<n; i++)
cout << arr[i] << " ";
return 0;
}
Output: 
3 7 4 8 2 6 1
Time complexity: O(n)
Auxiliary Space: O(1)

21)last index of 1
22) Print a given matrix in spiral form
#include <bits/stdc++.h>
using namespace std;

vector<int> spiralOrder(vector<vector<int>> &matrix)


{
vector<int> ans;

if (matrix.size() == 0)
return ans;

int R = matrix.size(), C = matrix[0].size();


bool seen[R][C];
int dr[] = { 0, 1, 0, -1 };
int dc[] = { 1, 0, -1, 0 };
int r = 0, c = 0, di = 0;

// Iterate from 0 to R * C - 1
for (int i = 0; i < R * C; i++) {
ans.push_back(matrix[r]);
seen[r] = true;
int cr = r + dr[di];
int cc = c + dc[di];

if (0 <= cr && cr < R && 0 <= cc && cc < C


&& !seen[cr][cc])
{
r = cr;
c = cc;
}
else
{
di = (di + 1) % 4;
r += dr[di];
c += dc[di];
}
}
return ans;
}

// Driver code
int main()
{
vector<vector<int>> a { { 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };

for(int x:spiralOrder(a))
{
cout << x << " ";
}
return 0;
}
Output:[1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10]
Complexity Analysis:
 Time Complexity: O(N)O(N), where NN is the total number of elements in the
input matrix. We add every element in the matrix to our final answer.
 Space Complexity: O(N)O(N), the information stored in seen and in ans.

Method 2: 

// C++ Program to print a matrix spirally

#include <bits/stdc++.h>
using namespace std;
#define R 3
#define C 6

void spiralPrint(int m, int n, int a[R][C])


{
int i, k = 0, l = 0;

/* k - starting row index


m - ending row index
l - starting column index
n - ending column index
i - iterator
*/

while (k < m && l < n) {


/* Print the first row from
the remaining rows */
for (i = l; i < n; ++i) {
cout << a[k][i] << " ";
}
k++;

/* Print the last column


from the remaining columns */
for (i = k; i < m; ++i) {
cout << a[i][n - 1] << " ";
}
n--;

/* Print the last row from


the remaining rows */
if (k < m) {
for (i = n - 1; i >= l; --i) {
cout << a[m - 1][i] << " ";
}
m--;
}

/* Print the first column from


the remaining columns */
if (l < n) {
for (i = m - 1; i >= k; --i) {
cout << a[i][l] << " ";
}
l++;
}
}
}

/* Driver Code */
int main()
{
int a[R][C] = { { 1, 2, 3, 4, 5, 6 },
{ 7, 8, 9, 10, 11, 12 },
{ 13, 14, 15, 16, 17, 18 } };

// Function Call
spiralPrint(R, C, a);
return 0;
}

Output
1 2 3 4 5 6 12 18 17 16 15 14 13 7 8 9 10 11
Complexity Analysis: 
 Time Complexity: O(m*n). 
To traverse the matrix O(m*n) time is required.
 Space Complexity: O(1). 
No extra space is required.

Method 3: (Recursive Approach)

// C++. program for the above approach


#include <iostream>
using namespace std;

#define R 4
#define C 4
// Function for printing matrix in spiral
// form i, j: Start index of matrix, row
// and column respectively m, n: End index
// of matrix row and column respectively
void print(int arr[R][C], int i, int j, int m, int n)
{
// If i or j lies outside the matrix
if (i >= m or j >= n)
return;

// Print First Row


for (int p = j; p < n; p++)
cout << arr[i][p] << " ";

// Print Last Column


for (int p = i + 1; p < m; p++)
cout << arr[p][n - 1] << " ";

// Print Last Row, if Last and


// First Row are not same
if ((m - 1) != i)
for (int p = n - 2; p >= j; p--)
cout << arr[m - 1][p] << " ";

// Print First Column, if Last and


// First Column are not same
if ((n - 1) != j)
for (int p = m - 2; p > i; p--)
cout << arr[p][j] << " ";

print(arr, i + 1, j + 1, m - 1, n - 1);
}

// Driver Code
int main()
{

int a[R][C] = { { 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };

// Function Call
print(a, 0, 0, R, C);
return 0;
}

Output
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
Complexity Analysis: 
 Time Complexity: O(m*n). 
To traverse the matrix O(m*n) time is required.
 Space Complexity: O(1). 
No extra space is required
 .
Method 4: (DFS Recursive Approach)
#include <iostream>
#include <vector>
using namespace std;
#define R 4
#define C 4

bool isInBounds(int i, int j)


{
if (i < 0 || i >= R || j < 0 || j >= C)
return false;
return true;
}

// check if the postion is blocked


bool isBlocked(int matrix[R][C], int i, int j)
{
if (!isInBounds(i, j))
return true;
if (matrix[i][j] == -1)
return true;
return false;
}

// DFS code to traverse spirally


void spirallyDFSTravserse(int matrix[R][C], int i, int j,
int dir, vector<int>& res)
{
if (isBlocked(matrix, i, j))
return;
bool allBlocked = true;
for (int k = -1; k <= 1; k += 2)
{
allBlocked = allBlocked
&& isBlocked(matrix, k + i, j)
&& isBlocked(matrix, i, j + k);
}
res.push_back(matrix[i][j]);
matrix[i][j] = -1;
if (allBlocked)
{
return;
}

// dir: 0 - right, 1 - down, 2 - left, 3 - up


int nxt_i = i;
int nxt_j = j;
int nxt_dir = dir;
if (dir == 0)
{
if (!isBlocked(matrix, i, j + 1))
{
nxt_j++;
}
else
{
nxt_dir = 1;
nxt_i++;
}
}
else if (dir == 1)
{
if (!isBlocked(matrix, i + 1, j))
{
nxt_i++;
}
else {
nxt_dir = 2;
nxt_j--;
}
}
else if (dir == 2)
{
if (!isBlocked(matrix, i, j - 1))
{
nxt_j--;
}
else
{
nxt_dir = 3;
nxt_i--;
}
}
else if (dir == 3)
{
if (!isBlocked(matrix, i - 1, j))
{
nxt_i--;
}
else
{
nxt_dir = 0;
nxt_j++;
}
}
spirallyDFSTravserse(matrix, nxt_i, nxt_j, nxt_dir,
res);
}

// to traverse spirally
vector<int> spirallyTraverse(int matrix[R][C])
{
vector<int> res;
spirallyDFSTravserse(matrix, 0, 0, 0, res);
return res;
}

// Driver Code
int main()
{
int a[R][C] = { { 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };

// Function Call
vector<int> res = spirallyTraverse(a);
int size = res.size();
for (int i = 0; i < size; ++i)
cout << res[i] << " ";
cout << endl;
return 0;
}
Output
1 2 3 4 8 12 16 15 14 13 9 5 6 7 11 10
Complexity Analysis:
Time Complexity: O(m*n). To traverse the matrix O(m*n) time is required.
Space Complexity: O(1). No extra space is required (without consideration of the stack
used by the recursion). 

23) Given an array of numbers, program to arrange the numbers to form the largest
number

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

// A comparison function which


// is used by sort() in
// printLargest()
int myCompare(string X, string Y)
{
// first append Y at the end of X
string XY = X.append(Y);

// then append X at the end of Y


string YX = Y.append(X);

// Now see which of the two


// formed numbers is greater
return XY.compare(YX) > 0 ? 1 : 0;
}

// The main function that prints


// the arrangement with the
// largest value. The function
// accepts a vector of strings
void printLargest(vector<string> arr)
{

// Sort the numbers using


// library sort function. The
// function uses our comparison
// function myCompare() to
// compare two strings. See
// http://www.cplusplus.com/reference/
// algorithm/sort/
// for details
sort(arr.begin(), arr.end(), myCompare);

for (int i = 0; i < arr.size(); i++)


cout << arr[i];
}

// Driver code
int main()
{
vector<string> arr;

// output should be 6054854654


arr.push_back("54");
arr.push_back("546");
arr.push_back("548");
arr.push_back("60");
printLargest(arr);

return 0;
}

Output
6054854654
Time Complexity:  O(nlogn) ,sorting is considered to have running time complexity of
O(nlogn) and the for loop runs in O(n) time.
Auxiliary Space: O(1).

You might also like