Maximum sum of non adjacent numbers in a circular array - algorithm

I need to find the maximum sum of non continous subsequence, I have the following code.
public int maxSumInSubsequence(int[] data) {
if (data == null) return 0;
int n = data.length;
// maxSum[i] == the maximum sum of subsequences of data[0 .. i] that include data[i]
int[] maxSum = new int[n];
for (int i=0; i<n; ++i) {
maxSum[i] = data[i];
// maxSum[i-1] includes data[i-1] and thus cannot include data[i]
for (int j=0; j<i-1; ++j) {
maxSum[i] = Math.max(data[i] + maxSum[j], maxSum[i]);
}
}
// find the max of all subsequences
int max = 0;
for (int i=0; i<n; ++i) {
max = Math.max(max, maxSum[i]);
}
return max;
}
This works fine, but how do I modify it to exclude the first and the last element from calculation.

Iterate over the array to construct another array with starting element as the ith element and of length n-1 that wraps around the array.
Execute maxSumInSubsequence over each constructed array and find the resultant maximum.
Also, as mentioned in another answer, maxSumInSubsequence could be optimized to have O(n) time complexity.
public int maxSumInSubsequence(int[] data) {
if (data == null) return 0;
int n = data.length;
if (n <= 2) return 0;
// maxSum[i] == the maximum sum of subsequences of data[0 .. i] that include data[i]
int[] maxSum = new int[n];
for (int i=0; i<n; ++i) {
maxSum[i] = data[i];
// maxSum[i-1] includes data[i-1] and thus cannot include data[i]
for (int j=0; j<i-1; ++j) {
maxSum[i] = Math.max(data[i] + maxSum[j], maxSum[i]);
}
}
// find the max of all subsequences
int max = 0;
for (int i=0; i<n; ++i) {
max = Math.max(max, maxSum[i]);
}
return max;
}
public int maxCircularSumInSubsequence(int[] data) {
int n = data.length;
int max = 0;
for (int i = 0; i < n; i++) {
int[] circularData = new int[n-1];
for (int j = 0; j < n - 1; j++) {
circularData[j] = data[(i+j) % n];
}
max = Math.max(maxSumInSubsequence(circularData), max);
}
return max;
}

/*Function to return max sum such that no two elements
are adjacent */
int FindMaxSum(int arr[], int n)
{
int incl = arr[0];
int excl = 0;
int excl_new;
int i;
for (i = 1; i < n; i++)
{
/* current max excluding i */
excl_new = (incl > excl)? incl: excl;
/* current max including i */
incl = excl + arr[i];
excl = excl_new;
}
/* return max of incl and excl */
return ((incl > excl)? incl : excl);
}
Reference : http://www.geeksforgeeks.org/maximum-sum-such-that-no-two-elements-are-adjacent/

The basic logic is to just compute the sum for two possibilities: start i from 0 and then sum up with every alternate array no or start i with i and sum up with every alternate number from there and print the maximum of both.
arr=[5,5,10,100,10,50,1]
def max_sum_suchThatNoTwoElements_are_adjacent(arr,n,su,max_sum):
i=0
while i<n:
su+=arr[i]
if (i+1)<n:
max_sum+=arr[(i+1)]
i+=2
return max(max_sum,su)
print(max_sum_suchThatNoTwoElements_are_adjacent(arr,len(arr),0,0))

Related

Maximum sum Sequence such that no two elements are adjacent

My implementation of max sum is below but i need sequence which is giving max sum i looked on google and stackoverflow but nowhere sequence is output.
public int maxSum(int arr[]) {
int excl = 0;
int incl = arr[0];
for (int i = 1; i < arr.length; i++) {
int temp = incl;
incl = Math.max(excl + arr[i], incl);
excl = temp;
}
return incl;
}
So 3 2 7 10 should return (3 and 10) or 3 2 5 10 7 should return (3, 5 and 7) or {5, 5, 10, 100, 10, 5} will return (5, 100 and 5) or {1, 20, 3} will return 20
i exactly want this problem solution but return value i need is sequence of elements included in max sum instead of max sum value
You mean that in this array: [1,3,4,2,4,7,5,3] , calculate [1+4+4+5] and [3+2+7+3]
and return the bigger one?
If you do so, this is my algorithm:
public int maxSum(int arr[]) {
int sum1 = 0;
int sum2 = 0;
for(int i = 0; i < arr.length; i+=2)
sum1 += arr[i];
for(int i = 1; i < arr.length; i+=2)
sum2 += arr[i];
return Math.max(sum1, sum2);
}
Or this one:
public int maxSum(int arr[]) {
int sum1 = 0;
int sum2 = 0;
for(int i = 0; i < arr.length; i+=2)
sum1 += arr[i];
try {sum2 += arr[i + 1];} catch(ArrayIndexOutOfBoundsException e){}
}
return Math.max(sum1, sum2);
}
Looks similar to Longest Increasing Fragment problem(Top Down approach.)
Instead of having length of sequence, you can return sum of it. Also, instead of skipping one, skipping two to avoid adjacent elements.
#simplest and clean solution
public int maxSubsetSumNoAdjacent(int[] arr) {
if(arr.length == 0){
return 0;
}
if(arr.length == 1){
return arr[0];
}
int a =arr[0];
int b= 0;
int c =a;
int i=1;
while(i<arr.length){
a=arr[i]+b;
b=Math.max(c,b);
c=a;
i++;
}
return Math.max(a,b);
}

How to sort the boundary elements of a matrix in ascending order?

I've worked on this but when I'm entering the matrix, all the elements in the matrix are getting sorted! But I want to sort only the boundary elements in ascending order. Can some body please tell me my mistake?
int k,temp=0,sum=0;
k=n;
boolean b=true;
do
{
for(i=0;i<m;i++)
{
for(j=0;j<k-1;j++)
{
if(i!=0||j!=0)
{
if(A[i][j]>A[i][j+1])
{
temp=A[i][j];
A[i][j]=A[i][j+1];
A[i][j+1]=temp;
}
}
}
}
k-=1;
if(k<0)
b=false;
}while(b);
k=m;
do
{
for(i=0;i<k-1;i++)
{
for(j=0;j<n;j++)
{
if(i!=0||j!=0)
{
if(A[j][i]>A[j][i+1])
{
temp=A[j][i];
A[j][i]=A[j][i+1];
A[j][i+1]=temp;
}
}
}
}
k-=1;
if(k<0)
b=false;
}while(b);
System.out.println("REARRANGED MATRIX:");
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
System.out.print(A[i][j]+" ");
}
System.out.println();
}
Instead of using the condition 'if(i!=0||j!=0)' use 'if(i==0||i==2||j==0||j==2)'.This may solve the ambiguity you are having.Your mistake was that you have taken the number of rows and columns both to be greater than zero.the boundary elements are those where number of rows is 0 or 2 or number of columns is 0 or 2(by this I mean that only those elements which have coordinates with either i=0 or i=2 or j=0 or j=2 will be considered as boundary elements.matrix coordinates
I have one solution of this. I have used selection sort for doing this.At first I have sorted the matrix then displaying the boundary of the sorted array
import java.io.*;
class Boundary_Sorting
{
public static void main(String args[])throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
System.out.println("Enter the rows of the matrix=");
int m = Integer.parseInt(br.readLine());
System.out.println("Enter the column of the matrix=");
int n = Integer.parseInt(br.readLine());
int a[][] = new int[m][n];
int i,j;
System.out.println("Enter the elements of the matrix: ");
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
a[i][j]=Integer.parseInt(br.readLine());
}
}
System.out.println("**********************");
System.out.println("The original matrix is");
System.out.println("**********************");
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
System.out.print(a[i][j]+"\t");
}
System.out.println();
}
int B[] = new int[m*n]; //creating a 1D Array of size 'r*c'
int x = 0;
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
B[x] = a[i][j];
x++;
}
}
/*Sorting the 1D Array in Ascending Order*/
int t = 0;
for(i = 0; i < (m * n) - 1; i++)
{
for(j = i + 1; j < (m * n); j++)
{
if(B[i] > B[j])
{
t = B[i];
B[i] = B[j];
B[j] = t;
}
}
}
/*Saving the sorted 1D Array back into the 2D Array */
x = 0;
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
a[i][j] = B[x];
x++;
}
}
/* Printing the sorted 2D Array */
System.out.println("**********************");
System.out.println("The Sorted Array:");
System.out.println("**********************");
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
System.out.print(a[i][j]+"\t");
}
System.out.println();
}
System.out.println("**********************");
System.out.println("The boundary elements of the matrix is=");
System.out.println("**********************");
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
if(i==0 || j==0 || i == m-1 || j == n-1) //condition for accessing boundary elements
System.out.print(a[i][j]+"\t");
else
System.out.print(" \t");
}
System.out.println();
}
}
}

The fastest algorithm for returning max length of consecutive same value fields of matrix?

Here is the given example:
We have the function which takes one matrix and it's number of columns and it's number of rows and returns int (this is gonna be length). For example:
int function (int** matrix, int n, int m)
The question is what's the fastest algorithm for implementing this function so it returns the maximum length of consecutive fields with the same value (doesn't matter if those same values are in one column or in one row, in this example on picture it's the 5 fields of one column with value 8)?
Values can be from 0-255 (grayscale for example).
So in the given example function should return 5.
If this is a bottleneck and the matrix is large, the first optimization to try is to make one pass over the matrix in sequential memory order (row-by-row in C or C++) rather than two. This is because it's very expensive to traverse a 2d array in the other direction. Cache and paging behavior are the worst possible.
For this you will need a row-sized array to track the number of consecutive values in the current run within each column.
int function (int a[][], int m, int n) {
if (n <= 0 || m <= 0) return 0;
int longest_run_len = 1; // Accumulator for the return value.
int current_col_run_len[n]; // Accumulators for each column
int current_row_run_len = 1; // Accumulator for the current row.
// Initialize the column accumulators and check the first row.
current_col_run_len[0] = 1;
for (int j = 1; j < n; j++) {
current_col_run_len[j] = 1;
if (a[0][j] == a[0][j-1]) {
if (++current_row_run_len > longest_run_len)
longest_run_len = current_row_run_len;
} else current_row_run_len = 1;
}
// Now the rest of the rows...
for (int i = 1; i < m; i++) {
// First column:
if (a[i][0] == a[i-1][0]) {
if (++current_col_run_len[0] > longest_run_len)
longest_run_len = current_col_run_len[0];
} else current_col_run_len[0] = 1;
// Other columns.
current_row_run_len = 1;
for (int j = 1; j < n; j++) {
if (a[i][j] == a[i][j-1]) {
if (++current_row_run_len > longest_run_len)
longest_run_len = current_row_run_len;
} else current_row_run_len = 1;
if (a[i][j] == a[i-1][j]) {
if (++current_col_run_len[j] > longest_run_len)
longest_run_len = current_col_run_len[j];
} else current_col_run_len[j] = 1;
}
}
return longest_run_len;
}
You need to pass over each entry of the matrix at least once, so you can't possible do better than O(m*n).
The most straightforward way is to pass over each row and each column once. This will be two passes over the matrix, but the algorithm is still O(m*n).
Any attempt to do it in one pass will probably be a lot more complex.
int function (int** matrix, int n, int m) {
int best=1;
for (int i=0; i<m; ++i) {
int k=1;
int last=-1;
for (int j=0; j<n; ++j) {
if (matrix[i][j] == last) {
k++;
if (k > best) {
best=k;
}
}
else {
k=1;
}
last = matrix[i][j];
}
}
for (int j=0; j<n; ++j) {
int k=1;
int last=-1;
for (int i=0; i<m; ++i) {
if (matrix[i][j] == last) {
k++;
if (k > best) {
best=k;
}
}
else {
k=1;
}
last = matrix[i][j];
}
}
return best;
}

Number of binary trees with equal values

There is array of values:
1 - n_1 times
2 - n_2 times
...
k - n_k times
How many trees with this nodes exist?
I create simple algorythm:
int get_count(const vector<int> n_i) {
if (n_i.size() <= 1) {
return 1;
} else {
int total_count = 0;
for (int i = 0; i < n_i.size(); ++i) {
vector<int> first;
vector<int> second;
for (int j = 0; j < i; ++j) {
first.push_back(n_i[j]);
}
if (n_i[i] != 1) {
second.push_back(n_i[i] - 1);
}
for (int j = i + 1; j < n_i.size(); ++j) {
second.push_back(n_i[j]);
}
total_count += (get_count(first) * get_count(second));
}
return total_count;
}
}
Because
#(n_1, n_2, ... n_k) = #(n_1 - 1, n_2, ..., n_k) + #(n_1) #(n_2 - 1, ... n_k) + ... + #(n_1, ..., n_k - 1)
and
#(0, n_i, n_j, ...) = #(n_i, n_j, ...)
But my code is so slow.
Is there a final formula via Cathalan's numbers, for example?
I guess that the problem can be split into calculating the number of permutations and calculating the number of binary trees of given size. I converted my initial recursive Java code (which gives up on n1=10,n2=10,n3=10) into this iterative one:
static int LIMIT = 1000;
static BigInteger[] numberOfBinaryTreesOfSize = numberOfBinaryTreesBelow(LIMIT);
static BigInteger[] numberOfBinaryTreesBelow(int m) {
BigInteger[] arr = new BigInteger[m];
arr[0] = BigInteger.ZERO;
arr[1] = arr[2] = BigInteger.ONE;
for (int n = 3; n < m; n++) {
BigInteger s = BigInteger.ZERO;
for (int i = 1; i < n; i++)
s = s.add(arr[i].multiply(arr[n - i]));
arr[n] = s;
}
return arr;
}
static BigInteger[] fac = facBelow(LIMIT);
static BigInteger[] facBelow(int m) {
BigInteger[] arr = new BigInteger[m];
arr[0] = arr[1] = BigInteger.ONE;
for (int i = 2; i < m; i++)
arr[i] = arr[i - 1].multiply(BigInteger.valueOf(i));
return arr;
}
static BigInteger getCountFast(int[] arr) {
// s: sum of n_i
int s = 0; for (int i = 0; i < arr.length; i++) { s += arr[i]; }
// p: number of permutations
BigInteger p = fac[s]; for (int i = 0; i < arr.length; i++) { p = p.divide(fac[arr[i]]); }
BigInteger count = p.multiply(numberOfBinaryTreesOfSize[s]);
return count;
}
public static void main(String[] args) {
System.out.println(getCountFast(new int[]{ 150, 150, 150, 150, 150 }));
}
The LIMIT limits the sum of the n_i. The above example takes about two seconds on my machine. Maybe it helps you with a C++ solution.

Maximum value of column in matrix?

How can i find the maximum value of a column in a matrix using only 2 for's in Java?
for(int i = 1; i< N; i++)
for(int j = 1; j < M; j++)
i want to find the maxim for each column
public int findMaxInCol(int colIndex){
int max = Integer.Min;
for(int row=0;row<Matrix.Rows;row++){
if(matrix[row][colIndex] > max){
max = matrix[row]colIndex];
}
}
return max;
}
void int findMaxOfMaxes() {
int maxOfMaxs = Integer.min;
for(int col=0;col<j;col++){
int maxInCol = findMaxInCol(col);
if( maxInCol > maxOfMaxs)
maxOfMaxs = maxInCol;
}
return maxOfMaxs
}
//pseudocode
//editing after finding that you wanted max in a matrix. You are right, you need 2 for loops.

Resources