You are on page 1of 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