Maximum sum Sequence such that no two elements are adjacent - algorithm

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

Related

Find minimum cost of tickets

Find minimum cost of tickets required to buy for traveling on known days of the month (1...30). Three types of tickets are available : 1-day ticket valid for 1 days and costs 2 units, 7-days ticket valid for 7 days and costs 7 units, 30-days ticket valid for 30 days and costs 25 units.
For eg: I want to travel on [1,4,6,7,28,30] days of the month i.e. 1st, 4th, 6th ... day of the month. How to buy tickets so that the cost is minimum.
I tried to use dynamic programming to solve this but the solution is not giving me the correct answer for all cases. Here is my solution in Java :
public class TicketsCost {
public static void main(String args[]){
int[] arr = {1,5,6,9,28,30};
System.out.println(findMinCost(arr));
}
public static int findMinCost(int[] arr) {
int[][] dp = new int[arr.length][3];
int[] tDays = {1,7,30};
int[] tCost = {2,7,25};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < 3; j++) {
if (j==0){
dp[i][j]= (i+1)*tCost[j];
}
else{
int c = arr[i]-tDays[j];
int tempCost = tCost[j];
int k;
if (c>=arr[0] && i>0){
for (k = i-1; k >= 0; k--) {
if (arr[k]<=c){
c = arr[k];
}
}
tempCost += dp[c][j];
int tempCostX = dp[i-1][j] + tCost[0];
tempCost = Math.min(tempCost,tempCostX);
}
dp[i][j] = Math.min(tempCost,dp[i][j-1]);
}
}
}
return dp[arr.length-1][2];
}
}
The solution doesn't work for {1,7,8,9,10} input, it gives 10 but the correct answer should be 9. Also, for {1,7,8,9,10,15} it give 13 but the correct is 11.
I have posted my solution not for other to debug it for me but just for reference. I was taken a bottom-up dynamic programming approach for this problem. Is this approach correct?
Let MC(d) denote the minimum cost that will pay for all trips on days 1 through d. The desired answer is then MC(30).
To calculate MC(d), observe the following:
If there's no trip on day d, then MC(d) = MC(d − 1).
As a special case, MC(d) = 0 for all d ≤ 0.
Otherwise, the minimum cost involves one of the following:
A 1-day pass on day d. In this case, MC(d) = MC(d − 1) + 2.
A 7-day pass ending on or after day d. In this case, MC(d) = min(MC(d − 7), MC(d − 6), …, MC(d − 1)) + 7.
And since MC is nondecreasing (adding a day never reduces the minimum cost), this can be simplified to MC(d) = MC(d − 7) + 7. (Hat-tip to Ravi for pointing this out.)
A 30-day pass covering the whole period. In this case, MC(d) = 25.
As you've realized, dynamic programming (bottom-up recursion) is well-suited to this.
For ease of coding, I suggest we start by converting the list of days into a lookup table for "is this a trip day?":
boolean[] isDayWithTrip = new boolean[31]; // note: initializes to false
for (final int dayWithTrip : arr) {
isDayWithTrip[dayWithTrip] = true;
}
We can then create an array to track the minimum costs, and populate it starting from index 0:
int[] minCostUpThroughDay = new int[31];
minCostUpThroughDay[0] = 0; // technically redundant
for (int d = 1; d <= 30; ++d) {
if (! isDayWithTrip[d]) {
minCostUpThroughDay[d] = minCostUpThroughDay[d-1];
continue;
}
int minCost;
// Possibility #1: one-day pass on day d:
minCost = minCostUpThroughDay[d-1] + 2;
// Possibility #2: seven-day pass ending on or after day d:
minCost =
Math.min(minCost, minCostUpThroughDay[Math.max(0, d-7)] + 7);
// Possibility #3: 30-day pass for the whole period:
minCost = Math.min(minCost, 25);
minCostUpThroughDay[d] = minCost;
}
And minCostUpThroughDay[30] is the result.
You can see the above code in action at: https://ideone.com/1Xx1fd.
One recursive solution in Python3.
from typing import List
def solution(A: List[int]) -> int:
if not any(A):
return 0
tickets = {
1: 2,
7: 7,
30: 25,
}
import sys
min_cost = sys.maxsize
size = len(A)
for length, price in tickets.items():
current_cost = price
idx = 0
last_day = A[idx] + length
while idx < size and A[idx] < last_day:
idx += 1
if current_cost > min_cost:
continue
current_cost += solution(A[idx:])
if current_cost < min_cost:
min_cost = current_cost
return min_cost
if __name__ == '__main__':
cases = {
11: [1, 4, 6, 7, 28, 30],
9: [1, 7, 8, 9, 10],
}
for expect, parameters in cases.items():
status = (expect == solution(parameters))
print("case pass status: %s, detail: %s == solution(%s)" %
(status, expect, parameters))
public class Main03v3
{
public static void main(String[] args)
{
int[] A = {1,7,8,9,10,15,16,17,18,21,25};
System.out.println("Traveling days:\r\n "+Arrays.toString(A));
int cost = solution(A);
System.out.println("\r\nMinimum cost is " + cost);
System.out.println("\r\n" + new String(new char[40]).replace("\0", "-"));
}
public static int solution(int[] A)
{
if (A == null) return -1;
int sevenDays = 7;
int dayCost = 2, weekCost = 7, monthCost = 25;
int ratio_WeekAndDays = weekCost / dayCost;
int len = A.length;
if (len == 0) return -1;
if (len <= 3) return len * dayCost;
int cost[] = new int[len];
int i = 0;
while (i < len)
{
int startIdx = i, endIdx = i + 1;
while (endIdx < len && A[endIdx]-A[startIdx] < sevenDays)
endIdx++;
if (endIdx-startIdx > ratio_WeekAndDays)
{
if (endIdx >= startIdx + sevenDays)
endIdx = startIdx + sevenDays;
int j = startIdx;
cost[j] = ((j == 0) ? 0 : cost[j-1]) + weekCost;
while (++j < endIdx) {
cost[j] = cost[j-1];
}
i = j;
}
else
{
cost[i] = ((i == 0) ? 0 : cost[i-1]) + dayCost;
i++;
}
}
int finalCost = Math.min(cost[len-1], monthCost);
return finalCost;
}
}
Find minimum cost of tickets in JavaScript
case 1 : if input is [1,7,8,9,10] then the required output is 9
case 2 : if input is [1,7,8,9,10,15] then the required output is 11
function calMinCosts(arr){
if(!arr || arr.length===0)
return 0;
var len = arr.length;
var costsOfDateArr = Array.apply(null,{length:arr[len-1]+1}).map(()=>0);
var price1=2,price2=7,price3=25;
var days=7;
var index=0,n=costsOfDateArr.length;
for(var i=1;i<n;i++){
if(i===arr[index]){
if(i>=days+1){
costsOfDateArr[i] = Math.min(costsOfDateArr[i-days-1]+price2, costsOfDateArr[i-1]+price1);
}else{
costsOfDateArr[i] = Math.min(costsOfDateArr[0]+price2, costsOfDateArr[i-1]+price1);
}
index+=1;
}else{
costsOfDateArr[i] = costsOfDateArr[i-1];
}
}
return Math.min(price3,costsOfDateArr[n-1]);
}
console.log(calMinCosts([1,7,8,9,10]))
console.log(calMinCosts([1,7,8,9,10,15]))
Here is the C++ solution including print outs
#include <vector>
#include <iostream>
#include <cmath>
#include <algorithm>
int compute(std::vector<int> &A)
{
int sum[A.size()][A.size()+1];
for (int i = 0; i < A.size(); i++)
{
for(int j =0; j < A.size(); j++)
{
sum[i][j]=2;
}
}
for (int k = 0; k < A.size();k++)
{
sum[k][A.size()]=0;
}
for (int i = 0; i < A.size(); i++)
{
for(int j = 0; j < A.size(); j++)
{
if (i!=j)
{
if (sum[i][i] != 7)
{
int temp = abs(A[j]-A[i]);
if (temp<7 && abs(j-i)>=3)
{
sum[i][i]=7;
sum[i][j]=7;
if (i>j)
{
for(int k = j;k < i;k++)
sum[i][k]=7;
}
else
{
for(int k = i;k < j;k++)
sum[i][k]=7;
}
}
}
}
}
}
for (int i = 0; i < A.size(); ++i)
{
for(int j = 0; j < A.size(); ++j)
{
if (sum[i][j]==7)
{
sum[i][A.size()]+=1;
}
}
}
for (int i = 0; i < A.size(); ++i)
{
for (int j = 0; j < A.size()+1; ++j)
std::cout<<sum[i][j]<<" ";
std::cout<<std::endl;
}
int result = 0;
int row = A.size()-1;
int column = A.size()-1;
while(1)
{
int value = sum[row][A.size()];
if (value == 0)
value=1;
int temp = sum[row][column];
result += temp;
row = row-value;
column = column-value;
while (sum[row][column+1]==7 && row>=0)
{
row-=1;
column-=1;
result+=2;
}
if (row < 0)
break;
}
return result;
}
int solution(std::vector<int> &A) {
if (A.size() > 24)
return 25;
if (A.size() <= 3)
return A.size() * 2;
return std::min(25,compute(A));
}
int main()
{
std::vector<int> AA={1,2,3,4,5,29,30};
std::vector<int> B={1,2,3,4,5};
std::vector<int> A={1,2,3,4,5,9,10,11,12,13,14,17,18,20,21};
std::vector<int> C={1,2,3,12};
std::vector<int> D={1,2,3,4,12,13,14,15,29,30};
std::vector<int> DD={1,2,3,4,5,14,17,18,19,20,23,28,29,30};
std::vector<int> CC={1,2,3,4,5,6,7,9,14,17,18,19,20,23,28,29,30};
std::cout<<solution(AA)<<std::endl;
std::cout<<solution(D)<<std::endl;
std::cout<<solution(B)<<std::endl;
std::cout<<solution(A)<<std::endl;
std::cout<<solution(C)<<std::endl;
std::cout<<solution(DD)<<std::endl;
std::cout<<solution(CC)<<std::endl;
return 0;
}
Solved using the same approach of bottom-up dynamic programming. Here is the full solution :
public class PublicTicketCost {
public static void main(String args[]){
int[] arr = {1,7,8,9,10,15,16,17,18,21,25};
int[] tDays = {1,7,30};
int[] tCost = {2,7,25};
System.out.println(minCost(arr, tDays, tCost));
}
public static int minCost(int[] arr, int[] tDays, int[] tCost) {
int[][] dp = new int[arr.length][tDays.length];
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < tDays.length; j++) {
int prevDayIndex = findPrevDayIndex(arr,i,tDays,j);
int prevCost = prevDayIndex>=0 ? dp[prevDayIndex][tDays.length-1] : 0;
int currCost = prevCost + tCost[j];
if(j-1>=0){
currCost = Math.min(currCost, dp[i][j-1]);
}
dp[i][j] = currCost;
}
}
//print(dp);
return dp[arr.length-1][tDays.length-1];
}
private static void print(int arr[][]){
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[0].length; j++) {
System.out.print(arr[i][j]+" ");
}
System.out.println();
}
}
private static int findPrevDayIndex(int[] arr, int i, int[] days, int j){
int validAfterDate = arr[i] - days[j];
if (validAfterDate<1){
return -1;
}
for (int k = i-1; k >= 0; k--) {
if (arr[k]<=validAfterDate){
return k;
}
}
return -1;
}
}
http://ideone.com/sfgxGo

Find zeroes to be flipped so that number of consecutive 1’s is maximized

Find zeroes to be flipped so that number of consecutive 1’s is maximized.
Input: arr[] = {1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1}
m = 2
Output: 5 7
We are allowed to flip maximum 2 zeroes. If we flip
arr[5] and arr[7], we get 8 consecutive 1's which is
maximum possible under given constraints .
Now if we were to find just the maximum number of 1's that is possible, is it possible to solve using dynamic programming approach?
This problem can be solved in linear time O(N) and linear space O(N). Its not full fledged dynamic programming, but its similar to that as it uses precomputation.
Data Structures Used:
1.left: It is an integer array, of same length as given array. It is precomputed such that for every position i:
left[i] = Number of consecutive 1's to the left position i
2.right: It is an integer array, of same length as given array. It is precomputed such that for every position i:
right[i] = Number of consecutive 1's to the right position i
These can be computed in single traversal of the array.Assuming arr is the original array, following pseudocode does the job:
Pseudocode for populating left array
left()
{
int count = 0;
for(int i = 0;i < arr length; ++i)
{
if(i == 0)
{
left[i] = 0;
if(arr[i] == 1)
count++;
continue;
}
else
{
left[i] = count;
if(arr[i] == 1)
count++;
else count = 0;
}
}
}
Pseudocode for populating right array
right()
{
int count = 0;
for(int i = arr length - 1;i >= 0; --i)
{
if(i == arr length - 1)
{
right[i] = 0;
if(arr[i] == 1)
count++;
continue;
}
else
{
right[i] = count;
if(arr[i] == 1)
count++;
else count = 0;
}
}
}
Now the only thing we have to do is :check all pair of positions i and j (i < j) such that arr[i] = 0 and arr[j] = 0 and for no position between i and j arr[i] should be 0 and Keep track of the pair for which we get maximum value of the following:
left[i] + right[j] + right[l]
You could also use left[i] + right[j] + left[r].
left[i] tells the number of consecutive 1's to the left of position i and right[j] tells the number of consecutive 1's to the right of position j and the number of consecutive 1's between i and j can be counted be left[r] OR right[l], and therefore, we have two candidate expressions.
This can also be done in single traversal, using following pseudocode:
max_One()
{
max = 0;
l = -1, r = -1;
for(int i = 0;i < arr length; ++i)
{
if(arr[i] == 0)
{
if(l == -1)
l = i;
else
{
r = i;
if(left[l] + right[r] + right[l] > max)
{
max = left[l] + right[r] + right[l];
left_pos = l;
right_pos = r;
}
l = r;
}
}
}
}
You should use sliding window concept here - use start and end vars to store index of range. Whenever you encounter a 0, increment the counter of zeros received. Include it in current length.. If zeros encounter equals m+1, increment start till you encounter 0.
public static int[] zerosToFlip(int[] input, int m) {
if (m == 0) return new int[0];
int[] indices = new int[m];
int beginIndex = 0;
int endIndex = 0;
int maxBeginIndex=0;
int maxEndIndex=0;
int zerosIncluded = input[0] == 0 ? 1 : 0;
for (int i = 1; i < input.length; i++) {
if (input[i] == 0) {
if (zerosIncluded == m) {
if (endIndex - beginIndex > maxEndIndex - maxBeginIndex){
maxBeginIndex = beginIndex;
maxEndIndex = endIndex;
}
while (input[beginIndex] != 0) beginIndex++;
beginIndex++;
} else {
zerosIncluded++;
}
}
endIndex++;
}
if (endIndex - beginIndex > maxEndIndex - maxBeginIndex){
maxBeginIndex = beginIndex;
maxEndIndex = endIndex;
}
int j = 0;
for (int i = maxBeginIndex; i <= maxEndIndex; i++) {
if (input[i] == 0) {
indices[j] = i;
++j;
}
}
return indices;
}

Maximum sum of non adjacent numbers in a circular array

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))

How to sort an array in a single loop?

So I was going through different sorting algorithms. But almost all the sorting algorithms require 2 loops to sort the array. The time complexity of Bubble sort & Insertion sort is O(n) for Best case but is O(n^2) as worst case which again requires 2 loops. Is there a way to sort an array in a single loop?
Here, a single-loop Bubble Sort in Python:
def bubbly_sortish(data):
for _ in xrange(len(data)**2):
i, j = _/len(data), _%len(data)
if i<j and data[i] > data[j]:
data[i], data[j] = data[j], data[i]
A = [5, 1, 2, 3, 5, 6, 10]
bubbly_sortish(A)
print A
Of course this is a joke. But this shows the number of loops has little to do with algorithm complexity.
Now, if you're asking if it is possible to sort an array with O(n) comparisons, no, it's not possible. The lower bound is Ω(n log n) for comparison-based sorting algorithms.
int list[] = { 45, 78, 22, 96, 10, 87, 68, 2 };
for (int i = 1; i < list.length; i++) {
if (list[i] < list[i - 1]) {
list[i] = list[i] + list[i - 1];
list[i - 1] = list[i] - list[i - 1];
list[i] = list[i] - list[i - 1];
i = 0;
}
}
System.out.print("Sorted array is : ");
for (int i = 0; i < list.length; i++) {
System.out.print(list[i] + " ");
}
Single Loop Bubble Sort using C++
int a[7]={5,7,6,2,4,3,1};
int temp = 0;
int j = 0;
for(int i = 0 ; i<a[]-1 ; i++)
{
int flag = 0;
if(a[i]>a[i+1])
{
temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
flag = 1;
}
if(i == 7-2-j)
{
if(!flag) break;
i = -1;
j++;
}
}
In the general case you have O(n lg n) as an average.
But in particular cases, the best case is O(n), which I consider close enough to what you'd call "only one loop", even though the implementation may show more than one instance of the for keyword. And the good news with that, is that you're not depending on luck to make your best case a reality. Provided you know a few properties about your data, you can pick some specific algorithms. For example :
3-way quicksort runs very near O(n) when you have a lot of items with only a few distinct sorting keys (think server log entries as items and dates as keys).
Counting sort runs in O(n+k) if your keys are easily indexable (like a character set, or small integers), and the index has a known upper bound k.
Burstsort will run in O(wn) if you're dealing with strings of maximum length w.
Those are but three examples. There are many more, way too many to recall from the top of my head, for many types of constrained data sets.
If you have a real-life case at hand where O(n lg n) is not good enough, it's well worth doing some proper research, provided you identified a few interesting properties in your data.
javascript:
function bruteForce(arr){
for(var i=0;i<arr.length; ){
if(arr[i+1]< arr[i]){
var temp = arr[i];
arr[i]=arr[i+1];
arr[i+1] = temp;
i--;
if(i === -1) i=0;
}else i++;
}
return arr;
}
alert(bruteForce([2,3,4,5,6,23,1,1]));
Copy the code and paste in URL of the browser and hit enter. If the javascript: is missed then add it.
Here is the code to sort array using only single loop.
var array = [100, 110, 111, 1, 3, 19, 1, 11, -10]
var i = 1
while i < array.count - 1 {
if array[i] > array[i + 1] {
let temp = array[i];
array[i] = array[i + 1];
array[i + 1] = temp;
i = -1;
}
i = i + 1;
}
print(array)
Here is a working version for your given example:
One very fast efficiant and logical way of doing the problem works if you know the range of the values to be sorted, for example
0 <= val <= 100 where val is integer.
Then you can do it with a single read and write operation in only two loops... one for reading the array, one for writing it sorted:
Use a second array where the indices represent values 0-100, store in it the number of times every value 0-100 is encountered, for example val = 100 could exist 234 times in your target array...
There is only one loop for reading and one loop for writing, which is computationally as efficient as one loop which would do both the reading and the writing and faster than a loop that uses comparison... If you insist, you can do it in a single loop twice as long as the target array's length and reset i value to zero on the new array write operation.
The second loop simply writes in order the count of every value encountered in the first array.
Single loop array sort:
for(int i = 0, j=i+1; i < arr.length && j<arr.length;)
{
if(arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i=0;
j=i+1;
}
else
{
i++;
j++;
}
}
public void sortArrayUsingSingleLoop(int[] intArray) {
int temp;
boolean swap = false;
for(int i=0;i<intArray.length-1;i++){
if(intArray[i]>intArray[i+1]){
temp=intArray[i];
intArray[i]=intArray[i+1];
intArray[i+1]=temp;
swap=true;
}
if(swap &&i==intArray.length-2){
i=-1;swap=false;
}
}
}
The following code is in php. you can test the code on https://paiza.io/projects/4pAp6CuB-e9vhGIblDNCZQ.
$a = [8,3,4,9,1];
for($i=0;$i<count($a)-1;$i++){
if($a[$i] > $a[$i+1]){
$temp = $a[$i];
$a[$i] = $a[$i+1];
$a[$i+1] = $temp;
$i = -1;
}
}
print_r($a);
public class SinleLoopeSorting {
public static void main(String[] args) {
Integer[] x = new Integer[] { 1, 7, 8, 0, 4, 2, 3 };
for (int i = 0; i < x.length - 1; i++) {
if (x[i] > x[i + 1]) {
int p = x[i];
x[i] = x[i + 1];
x[i + 1] = p;
i = -1;
}
}
for (int i = 0; i < x.length; i++) {
System.out.println(x[i]);
}
}
}
This can be used to sort array usinga single loop:-
Points to be noed:
updating the value of i to -1 so that it alwasy starts from 0 after i++
reducing the length(size--) of array as maximum valued element ends up at the end for every time the loop completes
Code:
void sort(int *arr,int size){
int i;
for (i = 0; i <size; i++){
if(arr[i]>arr[i+1]){
arr[i]=arr[i]+arr[i+1];
arr[i+1]=arr[i]-arr[i+1];
arr[i]=arr[i]-arr[i+1];
if(i==size-2){
printf("%s\n","inside if loop" );
i=-1;
size--;
}
}
}
}
def my_sort(num_list):
x = 0
while x < len(num_list) - 1:
if num_list[x] > num_list[x+1]:
num_list[x], num_list[x+1] = num_list[x+1], num_list[x]
x = -1
x += 1
return num_list
print(my_sort(num_list=[14, 46, 43, 27, 57, 42, 45, 21, 70]))
#output [14, 21, 27, 42, 43, 45, 46, 57, 70]
Single for loop for insertion sort:
strong text
function insertionSort (array) {
for(var i = 1 ; i < array.length ;){
if(array[1] < array[0]) {
temp = array[i];
array[i] = array[i -1];
array[i -1] = temp;
}
if(array[i] < array[i-1]){
var temp = array[i]
array[i] = array[i -1]
array[i -1] = temp
i--
} else{i++}
}
return array
}
Sorting an array using single loop (javascript)
var arr = [4,5,2,10,3,7,11,5,1];
for(var i = 1; i < arr.length; i++)
{
if(arr[i] < arr[i-1])
{
arr[i] = arr[i] + arr[i-1];
arr[i-1] = arr[i] - arr[i-1];
arr[i] = arr[i] - arr[i-1];
i=0;
}
}
output : arr = [1, 2, 3, 4, 5, 5, 7, 10, 11]
The following code is in PHP to sort an array best case possible.
https://paiza.io/projects/r22X0VuHvPQ236jgkataxg
<?php
function quicksort($a){
$n = count($a);
$lt = [];
$gt = [];
if($n < 2){
return $a;
}else{
$f = $a[0];
}
for($i = 1;$i < $n ;$i++){
if($a[$i] > $f){
$gt [] = $a[$i];
}else{
$lt [] = $a[$i];
}
}
return array_merge(quicksort($lt),array($f),quicksort($gt));
}
$ar = [7,4,3,6,5,1,2];
echo "Input array => ".implode(' , ',$ar).'<br>';
$a = quicksort($ar);
echo "Output array => ".implode(' , ',$a);;
?>
Sorting an array using java in Single Loop:
public int[] getSortedArrayInOneLoop(int[] arr) {
int temp;
int j;
for (int i = 1; i < arr.length; i++) {
j = i - 1;
if (arr[i] < arr[j]) {
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
i = 1;
}
}
return arr;
}
Late to the party but hope this helps
java solution
for(int i=1;i< arr.length;i++) {
if(arr[i] < arr[i-1] ){
arr[i-1] += arr[i];
arr[i] = arr[i-1] - arr[i];
arr[i-1] -= arr[i];
i=0;
}
}
with python:
def sort(array):
n = len(array);
i = 0;
mod = 0;
if(len(array)<= 1):
return(array)
while n-1:
if array[mod] > array[mod+1]:
array[mod], array[mod+1] = array[mod+1], array[mod]
mod+=1
if mod+1 >= n:
n-=1
mod = 0
return array
#include<stdio.h>
void sort(int a[],int n,int k,int w)
{
int i,j,z,key;
n=n-1;
j = k+1;
key = a[j];
i = j-1;
while(i>0 && a[i]>key)
{
a[i+1] = a[i];
i = i-1;
}
a[i+1] = key;
k = k + 1;
if(n!=0)
{
sort(a,n,k,w);
}
}
int main()
{
int i,n,w,k=1,z=5,g;
printf("enter the size of an array\n");
scanf("%d",&n);
g=n;
int a[n];
for(i=1;i<=n;i++)
{
scanf("%d", &a[i]);
}
w = n;
sort(a,n-1,k,w);
for(i = 1; i <= n; i++)
{
printf("%d", a[i]);
}
}
Here is the solution. This might help you.
public int find2ndLargest() {
int[] arr = {1,3,14,25,7,20,11,30};
int temp;
// sort array
for (int i=0;i<arr.length-1;i++) {
if (arr[i]>arr[i+1]) {
temp = arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
i=0;
}
}
return arr[arr.length-2];
}
static int[] sort(int[] arr){
int idx = 0;
int len = arr.length - 1;
int counter = len;
while(true){
if(idx != len && arr[idx] > arr[idx+1]){
swap(arr, idx, idx + 1);
counter--;
}
idx++;
if(counter == len && idx == len){
break;
}
if(idx == len){
idx = 0;
counter = len;
}
}
return arr;
}
void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
it as much simple as below, please flow easy step
var arr=[5,1,4,3];
for(var i=0;i<arr.length-1;i++){
var num=arr[i];
var num2=arr[i+1];
//Check if first index value with next index value
if(num>num2){
var temp=arr[i];
arr[i]=arr[i+1];
arr[i+1]=temp;
//assign i=0 to re start the loop to check the index value
i=0;
}
}
console.log(arr)
you can use a while loop and play around with the index
int i=0;
int a[]={1,2,3,4,7,3};
while(i<a.length)
{
if((i+1<a.length && a[i]>a[i+1]) )
{
swap(i,i+1,a);
i=i-1;
}
if(i-1>=0 && a[i]<a[i-1] )
{
swap(i,i-1,a);
i=i-1;
}
else
i++;
}

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.

Resources