Java MergeSort: Compare and Swap Counters - java

I have the following MergeSort class and I have to implement compare and swap counters. Can someone please confirm if my compare and swap counters are in the right locations?
As you'll see, I have two class properties for the swap and compare counters. Where I'm not exactly positive is where A) I initialize the swapCount and compareCount (in runSort method or mergeSort method?) and B) where exactly swapCount++ in the merge method should be placed. I'm pretty sure compareCount++ is in the right place though.
Here's the code. Thanks in advance to all who reply!
public class MyMergeSort {
private int swapCount;
private int compareCount;
public void runSort() {
//this.compareCount = 0;
//this.swapCount = 0;
mergeSort(this.sortItems,0,sortItems.length);
}
public void mergeSort(String[] data, int first, int n) {
int n1; // Size of the first half of the array
int n2; // Size of the second half of the array
this.compareCount = 0;
this.swapCount = 0;
if (n > 1) {
// Compute sizes of the two halves
n1 = n / 2;
n2 = n - n1;
mergeSort(data, first, n1); // Sort data[first] through data[first+n1-1]
mergeSort(data, first + n1, n2); // Sort data[first+n1] to the end
// Merge the two sorted halves.
merge(data, first, n1, n2);
}
}
private void merge(String[] data, int first, int n1, int n2) {
String[] temp = new String[n1+n2]; // Allocate the temporary array
int copied = 0; // Number of elements copied from data to temp
int copied1 = 0; // Number copied from the first half of data
int copied2 = 0; // Number copied from the second half of data
int i; // Array index to copy from temp back into data
// Merge elements, copying from two halves of data to the temporary array.
while ((copied1 < n1) && (copied2 < n2)) {
compareCount++;
if (data[first + copied1].compareTo(data[first + n1 + copied2]) < 0) {
temp[copied++] = data[first + (copied1++)];
//swapCount++;
}
else {
temp[copied++] = data[first + n1 + (copied2++)];
swapCount++;
}
}
// Copy any remaining entries in the left and right subarrays.
while (copied1 < n1)
temp[copied++] = data[first + (copied1++)];
while (copied2 < n2)
temp[copied++] = data[first + n1 + (copied2++)];
// Copy from temp back to the data array.
for (i = 0; i < n1+n2; i++)
data[first + i] = temp[i];
}
}
** Update 11/28/2017 ** Good news. I think I finally found just what I was looking for:
http://www.cs.carleton.edu/faculty/adalal/teaching/f04/117/notes/nov08/Sort.java
Big thanks to the author of that code!

To implement proper counting, you need to increment the count value every time the thing you are counting occurs. For example:
if (n > 2) {
a = b;
swapCount++;
}
compareCount++; // because the condition of the if statement
This means you may need to structure your methods such that swapCount and compareCount are accessible, and rework your logic such that short-circuiting doesn't diverge from the actual count. For example, you could not write
if ((a > 5) && (b > 5)) {
...
}
and get an easy way of updating the compareCount because you'd need to add in logic to see if one compare was done, or two. To do that, you'd add at least an additional compare
if (a > 5) {
compareCount++;
} else {
compareCount += 2;
}
Instead it would be much better to simply write your compound comparison in a different way
if (a > 5) {
if (b > 5) {
}
compareCount++;
}
compareCount++;
Which reads more poorly in the "if statement" but is cleaner in determining the conditions for incrementing compareCount.

Related

CoinChange Problem with DP in Java using 2D array

I am implementing an algorithm to solve the Coin Change problem, where given an array that indicates types of coins (i.e. int[] coinValues = {1,4,6};) and a value to achieve (i.e. int totalAmount=8;), an array is returned where the value at position 0 indicates the minimum number of coins needed to achieve totalAmount. The rest of the array will keep a track of how many coins are needed to achieve the total sum.
An example input of coins = {1,4,6} and total = 8 should return the array [3,2,0,1]. However, my code is returning [1,2,0,1].
Another example would be coins = {2,4,8,16,34,40,64} and total = 50 should return the array [2, 0, 0, 0, 1, 1, 0, 0]. My code is not returning that result.
The algorithm is implemented with 2 methods: CoinChange and CoinCount. CoinChange creates the coin matrix and CoinCount keeps track of the coins required to achieve the total sum.
package P5;
import java.util.Arrays;
public class CoinChange7 {
public static int[] CoinChange(int[] v, int sum) {
int[][] aux = new int[v.length + 1][sum + 1];
// Initialising first column with 0
for(int i = 1; i <= v.length; i++) {
aux[i][0] = 0;
}
// Implementing the recursive solution
for(int i = 1; i <= v.length-1; i++) {
for(int j = 1; j <= sum; j++) {
if(i == 1) {
if(v[1] > j) {
aux[i][0]=999999999; //instead of Integer.MAX_VALUE
} else {
aux[i][j]=1 + aux[1][j-v[1]];
}
} else {
if(v[i] > j) { //choose best option ,discard this coin or use it.
aux[i][j] = aux[i - 1][j];
} else
aux[i][j] = Math.min(aux[i-1][j],1 + aux[i][j-v[i]]);
}
}
}
int []z=CoinCount(sum,aux,v);
return z; // Return solution to the initial problem
}
public static int[] CoinCount(int A, int[][] aux, int[] d){
int coin = d.length-1;
int limit=A;
int [] typo=new int[d.length+1]; //We create solution array, that will count no of coins
for (int k=0;k<typo.length;k++) {
typo[k]=0;
} while (coin>0 || limit>0){
if(limit-d[coin]>=0 && coin-1>=0){
if(1+aux[coin][limit-d[coin]]<aux[coin-1][limit]){
typo[coin+1]=typo[coin+1]+1;
limit=limit-d[coin];
} else {
coin=coin-1;
}
} else if(limit-d[coin]>=0) {
typo[coin+1]=typo[coin+1]+1;
limit=limit-d[coin];
} else if(coin-1>=0) {
coin=coin-1;
}
}
typo[0]= aux[d.length-1][A];
return typo; //return the final array with solutions of each coin
}
public static void main(String[] args) {
int[] coins = {1,4,6};
int sum = 8;
int[] x=CoinChange(coins,sum);
System.out.println("At least " + Arrays.toString(x) +" from set "+ Arrays.toString(coins)
+ " coins are required to make a value of " + sum);
}
}
Clarification
I don't know if you still need the answer to this question but I will try to answer it anyway.
First, there are a few things I would like to clarify. The coin change problem does not have a unique solution. If you want both the minimum of coins used to make the change and frequencies of coins usage, I think that depends on the approach used to solve the program and the arrangement of the coins.
For example: Take the coins to be [4,6,8] and amount = 12. You'll quickly see that the minimum coins required to make this change is 2. Going by your choice of output, the following are all correct: [2,0,2,0] and [2,1,0,1].
By the way, the Coin change problem can be solved in many ways. A simple recursive DP approach in Java is here. It only returns the min coins needed to make the change at O(nlog(n)) time and O(n) space.
Another approach is by using a 2D DP matrix (same with the approach you tried using) at both O(n^2) time and space. Explanation on how to use this approach is here. Please be careful with the explanation because it is not generally correct. I noticed it's almost the same as the one you used.
Your solution
I will mention a few things about your solution that may have affected the result.
The number of rows of the DP matrix is v.length not v.length + 1.
Based on your solution, this should not affect the result because I noticed you don't seem comfortable with zero indexes.
I think it is not necessary to initialize the first column of the DB matrix since the data type you used is int, which is 0 by default. Again, this does not affect the answer, though.
The way you filled row 1 (supposed to be the first row, but you ignored row 0) is not good and may affect the result of some solutions.
The only mistake I see there is that there is no uniform value to specify amounts (i.e. j) that cannot be solved using the single coin (i.e. v[0]). Negative numbers could have been better because any positive integer is a potential valid solution for the cell. You could use -1 (if you're going by the Leetcode instruction). This way, you'll easily know cells that contain invalid values while filling the rest of the matrix.
The way you compute aux[i][j] is wrong because you are using the wrong coins. you are using v[i] instead of v[i-1] since you aux.length is one bigger than the v.length.
I did not look at the countCoint method. It looks complex for a seemingly simple problem. Please see my solution.
My Solution
public int[] change(int[] coins, int amount){
int[][] DP = new int[coins.length][amount+1];
//fill the first column with 0
//int array contains 0 by default, so this part is not necessary
/*
for (int i = 0; i < coins.length; i++) {
DP[i][0] =0;
}
*/
//fill the first row.
//At 0th row, we are trying to find the min number of ways to change j amount using only
//one coin i.e. coins[0] (that is the meaning of DP[0][j];
for (int j = 1; j <= amount; j++) {
if(coins[0] > j || j % coins[0] != 0){
DP[0][j] = -1;
}else{
DP[0][j] = j /coins[0];
}
}
//iterate the rest of the unfilled DP
for (int i = 1; i < coins.length; i++) {
for (int j = 1; j < amount+1; j++) {
if(coins[i] > j){
DP[i][j] = DP[i-1][j];
}else {
int prev = DP[i-1][j];
int cur = 1+DP[i][j-coins[i]];
if(cur == 0){
DP[i][j] = DP[i-1][j];
} else if(prev == -1) {
DP[i][j] = 1 + DP[i][j - coins[i]];
}else{
DP[i][j] = Math.min(DP[i-1][j],1+DP[i][j-coins[i]]);
}
}
}
}
return countCoin(coins,amount,DP);
}
public int[] countCoin(int[] coins, int amount, int[][] DP){
int[] result = new int[coins.length+1];//The 1 added is to hold result.
int i = coins.length -1;
int j = amount;
//while the rest will contain counter for coins used.
result[0] = DP[i][j];
if(result[0] ==0 || result[0] ==-1)return result;
while (j > 0 ){
if(i-1 >= 0 && DP[i][j] == DP[i-1][j]){
i = i-1;
}else{
j = j - coins[i];
result[i+1] += 1;
}
}
return result;
}

What is the right way to solve Codility's PermMissingElem test? (Java)

I have the following problem taken from Codility's code testing exercises:
A zero-indexed array A consisting of N different integers is given. The array contains integers in the range [1..(N + 1)], which means that exactly one element is missing.
Your goal is to find that missing element.
Write a function:
class Solution { public int solution(int[] A); }
that, given a zero-indexed array A, returns the value of the missing element.
For example, given array A such that:
A[0] = 2
A[1] = 3
A[2] = 1
A[3] = 5
the function should return 4, as it is the missing element.
Assume that:
N is an integer within the range [0..100,000];
the elements of A are all distinct;
each element of array A is an integer within the range [1..(N + 1)].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(1), beyond input storage (not >counting the storage required for input arguments).
Elements of input arrays can be modified.
My approach was to convert the given array into an ArrayList, use the ArrayList to find the lowest and highest values inside the array, and iterate through all possible values from lowest to highest, and then return the missing value.
This solves the example problem, but my problem seems to be that I cannot get right answers under the following conditions of the given array:
"empty list and single element"
"the first or the last element is missing"
"single element"
"two elements"
What am I doing wrong, and what is the proper way to go about solving this problem?
This problem has a mathematical solution, based on the fact that the sum of consecutive integers from 1 to n is equal to n(n+1)/2.
Using this formula we can calculate the sum from 1 to N+1. Then with O(N) time complexity we calculate the actual sum of all elements in the array.
The difference between the full and actual totals will yield the value of the missing element.
Space complexity is O(1).
This problem is part of the Lessons of Time Complexity.
https://codility.com/media/train/1-TimeComplexity.pdf
In fact at the end there is the explanation on how to compute the sum of the elements in an array, without do any loop.
This is the final solution in Python3:
def solution(A):
n = len(A)+1
result = n * (n + 1)//2
return result - sum(A)
The problem statement clearly specifies that the array will consist of "N different integers", thus N must be at least 2. N=0 and N=1 simply do not make sense if we write them in English, e.g. "An array consisting of 0 different integers...".
A zero-indexed array A consisting of N different integers is given. The array contains integers in the range [1..(N + 1)], which means that exactly one element is missing.
With these initial conditions and stated assumptions, tests like "single element", "empty list", etc., are completely inappropriate.
Proper production code would most likely have to test for invalid conditions, but that wasn't a stated goal of the challenge.
Another 100% solution:
There is actually not even a need to use 64-bit integers to avoid the overflows that a couple of tests try to trigger (the ones with array size of 100000 at the time of writing). And you can get away with only one sum variable. The last line avoids overflows further by implementing n(n+1)/2 differently so that the division by two occurs "early":
C#:
class Solution {
public int solution(int[] A) {
var sum = 0;
for(int i = 0; i < A.Length; i++)
sum += A[i];
return A.Length % 2 == 0 ? -sum + (A.Length/2 + 1) * (A.Length+1)
: -sum + (A.Length/2 + 1) * (A.Length+2);
}
}
my solution in java 100%
Detected time complexity:
O(N)
import java.util.*;
class Solution {
public int solution(int[] arr) {
if(arr.length == 0) return 1;
int sumArr = 0;
for(int i=0; i < arr.length; i++){
sumArr = sumArr + arr[i];
}
int sumN = 0;
for(int i=1; i <= arr.length+1; i++){
sumN = sumN + i;
}
if(sumArr == sumN) return arr.length;
return sumN - sumArr;
}
}
You can use an Array to sort the element first and then use simple for loop to iterate over it, and find the missing value.
Here is my simple code with detected time complexity of O(N) or O(N * log(N)) in codility.
public static int solution(int[] A) {
int size = A.length;
int count = 1;
Arrays.sort(A);
for (int i = 0; i < size; i++) {
if (A[i] != count)
return count;
count++;
}
return count;
}
Here is the solution in PHP using the sum of consecutive integers from 1 to n is equal to n(n+1)/2.
function solution($A) {
$size = count($A) + 1;
$total = ($size * ($size + 1)) / 2;
return $total - array_sum($A);
}
java solution:
public int solution(int[] A) {
int nExpected = A.length + 1;
long seriesSumExpected = nExpected * (nExpected + 1L) / 2;
long seriesSum = getSum(A);
return (int) (seriesSumExpected - seriesSum);
}
private long getSum(int[] A) {
long sum = 0L;
for (int i : A) {
sum += i;
}
return sum;
}
Task Score: 100%
Correctness: 100%
Performance: 100%
private static int getMissingElementInArrayNew(int[] A) throws IOException {
double n = A.length + 1;
double totalSum = (double) ((n * (n + 1)) / 2);
for (int i = 0; i < A.length; i++) {
totalSum -= A[i];
}
return (int) (totalSum == 0 ? A.length + 1 : totalSum);
}
Here's another solution using JavaScript tested 100%.
function solution(A) {
let maximumNumber = A.length + 1;
let totalSum = (maximumNumber*(maximumNumber + 1))/2;
let partialSum = 0;
for(let i=0; i<A.length; i++) {
partialSum += A[i];
}
return totalSum - partialSum;
}
Golang solution:
func Solution(A []int) int {
n := len(A) + 1
total := n * (n + 1) /2
for _, e := range A {
total -= e
}
return total
}
Java solution got 100%:
public int solution(int[] A) {
Arrays.sort(A);
if (A.length == 0) {
return 1;
}
if (A[0] != 1) {
return 1;
}
for (int i = 0; i < A.length; i++) {
if (A[i] != i + 1) {
return A[i] - 1;
}
}
return A[A.length - 1] + 1;
}
While I value the math solution it's not that easy to understand.
So here's a simple solution with 100% score on codility.
import java.util.*;
public int solution(int[] A) {
int missing = 1; // missing number 1 already
Arrays.sort(A);
// check numbers one by one
for (int i = 0; i < A.length; i++) {
if (A[i] == missing) { // we found the missing number !
missing = A[i]+1; // add +1 and keep checking
}
}
return missing;
}
OBJECTIVE-C SOLUTION O(N) - SET Approach
Results given by Codility
Task Score: 100%
Correctness: 100%
Performance: 100%
Time Complexity
The worst case time complexity is O(N) or O(N * log(N))
Xcode Solution Here
+(int)SETSolution:(NSMutableArray*)array {
/******** Algorithm Explanation ********/
// FACTS
// Use of a NSSet to verify if the missing element exist or not.
// Edge case: when the array is empty [], we should return 1
// STEP 1
// validate the edge case
// STEP 2
// Generate a NSSet with the array elements in order to search an element faster
// STEP 3
// Use a for loop and find the current 'i' in the NSSset
// If an elements doesn't exist in the NSSet, that means it's the missing element.
int n = (int)[array count];
int missing = 0;
// STEP 1
if (n == 0) {
missing = 1;
return missing;
}
else {
// STEP 2
NSSet *elements = [NSSet setWithArray:array];
// STEP 3
for (int i = 1; i <= (n+1); i++) {
// O(N) or O(N * log(N)) depending of required iterations
if (![elements containsObject:[NSNumber numberWithInt:i]]) {
missing = i;
return missing;
}
}
return missing;
}
}
OBJECTIVE-C SOLUTION O(N) - XOR Approach
Results given by Codility
Task Score: 100%
Correctness: 100%
Performance: 100%
Time Complexity
The worst case time complexity is O(N) or O(N * log(N))
Xcode Solution Here
+(int)XORSolution:(NSMutableArray*)array {
/******** Algorithm Explanation ********/
// FACTS
// Use of XOR operator
// Edge case: when the array is empty [], we should return 1
// XOR of a number with itself is 0.
// XOR of a number with 0 is number itself.
// STEP 1
// XOR all the array elements, let the result of XOR be X1.
// STEP 2
// XOR all numbers from 1 to n, let XOR be X2.
// STEP 3
// XOR of X1 and X2 gives the missing number.
int n = (int)[array count];
// Edge Case
if(n==0){
return 1;
}
else {
// STEP 1
/* XOR of all the elements in array */
int x1 = 0;
for (int i=0; i<n; i++){
x1 = x1 ^ [[array objectAtIndex:i]intValue];
}
// STEP 2
/* XOR of all the elements from 1 to n+1 */
int x2 = 0;
for (int i=1; i<=(n+1); i++){
x2 = x2 ^ i;
}
// STEP 3
int missingElement = x1 ^ x2;
return missingElement;
}
}
100% solution in Swift 4:
public func solution(_ A : inout [Int]) -> Int {
// first we simply calculate the sum on the given array
var sum = 0
for element in A {
sum += element
}
// as the sum of consecutive ints is given by n(n+1)/2,
// we calculate the expected sum from 1 to n + 1
// (which is ((n+1)(n+2))/2) and substract the actual sum
// to get the missing element
return ((A.count + 1) * (A.count + 2) / 2) - sum
}
// Solution with LinQ.
// Task Score: 100%
// Correctness: 100%
// Performance: 100%
using System.Linq;
public static int GetPermMissingElem(int[] A)
{
if (A.Length <= 0)
return 1;
int size = A.Length;
System.Collections.Generic.List<int> missing = Enumerable.Range(1, A[size - 1]).Except(A.ToList()).ToList();
if (!missing.Any())
return A[size -1] + 1;
return missing.First();
}
This got 100% on Codality. It uses very basic math. For the array:
{2,3,1,5}
1,2,3,4,?
sum of all the indexes + 1 and plus the missing index + 1 to get what you total should be.
Then you can subtract the sum of the array: (1+2+3+4+5=15)-(2+3+1+5=11)=4
public int solution(int A[]) {
if (A == null) return 0;
if(A.length == 0) return 1;
int total = 0;
int max = A.length + 1;
for (int i = 0; i < A.length; i++) {
total += A[i];
max += i + 1;
}
return (max - total) < 0 ? 0 : (max - total);
}
This is one thing I had to look up though which irritates me and I don't understand.
if(A.length == 0) return 1;
This makes IMO no sense. If the array length is zero then it should be zero IMO.
I used this java code as a solution. Got 100%
class Solution {
public int solution(int[] A) {
int result = 0;
Set<Integer> set = new HashSet<>();
for (int x : A) {
set.add(x);
}
for (int x = 1; x < set.size() + 2; x++) {
if (!set.contains(x)) {
return x;
}
}
return result;
}
}
Ruby, 100% pass :
def solution(a)
n = a.length + 1
sum = n * (n + 1)/2
return sum - a.inject(0,:+)
end
I have trouble with this, but only because i did not understand all cases.
this is my solution in Java. Bit longer (i could not make it small) but score is 100%.
class Solution {
public int solution(int[] A) {
Arrays.sort(A);
if (A.length == 1) {
if (A[0] == 1) {
return A.length + 1;
} else {
return A[0] - 1;
}
}
for (int n = 0; n < A.length - 1; n++) {
if (A.length == 2) {
if (A[n] == 1) {
if (A[n] + 1 != A[n + 1]) {
return A[n] + 1;
}
return A.length + 1;
} else {
return 1;
}
} else {
if (A[0] != 1) {
return 1;
}
if (A[n] + 1 != A[n + 1]) {
return A[n] + 1;
}
}
}
return A.length + 1;
}
}
Analysis summary
The solution obtained perfect score.
Kind regards Nenad
using System;
// you can also use other imports, for example:
// using System.Collections.Generic;
// you can write to stdout for debugging purposes, e.g.
// Console.WriteLine("this is a debug message");
class Solution {
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
int i, j = 0, n = A.Length;
if (A != null && n != 0)
{
Array.Sort(A);
for (j = A[0], i = 0; i < n; i++, j++)
{
if (j == A[i]) continue;
else return j;
}
if (i == n) return (A[0] == 2) ? 1 : ++A[--n];
}
else return 1;
return -1;
}
}
Swift solution 100% pass
import Foundation
import Glibc
public func solution(_ A : inout [Int]) -> Int {
let sortedArray = A.sorted(by: { $0 < $1 })
for i in 0..<sortedArray.count {
if sortedArray[i] != i+1 {
return i+1
}
}
return A.count + 1
}
Java Solution:
// Import Dependencies
import java.util.*;
class Solution {
public int solution(int[] A) {
// write your code in Java SE 8
long N = A.length+1;
long realSum = N*(N+1)/2;
long foundSum = 0;
for(int i=0;i<N-1;i++){
foundSum = foundSum + A[i];
}
long answer = (realSum - foundSum);
return (int)(answer);
}
}
Here is my solution.
const assert = require("assert").strict;
function solution(A) {
const n = A.length + 1;
const sum = (n * (n + 1)) / 2;
const sum2 = A.reduce((a, b) => a + b, 0);
return sum - sum2;
}
assert.strictEqual(solution([2, 3, 1, 5]), 4);
assert.strictEqual(solution([]), 1);
assert.strictEqual(solution([1]), 2);
Attaching solution written in kotlin:
fun solution(A: IntArray): Int {
val lastElement = A.size + 1
// including missing element
val arraySize = A.size + 1L
var result = (arraySize * (1 + lastElement)) / 2
A.forEach {
result -= it
}
return result.toInt()
}
P.S. Arithmetic progression sum formula was used.
P.P.S. Perform operations using Long primitive type, as you can face some Int limits.
I think the best way of doing it is via XOR which is clean, elegant and fast. No math knowledge required, just CS! This has also another advantage over the other way of summing it up where we won't get an integer overflow since we are just doing bitwise operations.
O(n) in time, O(1) in space.
This is how the code looks like (Javascript), just a single loop required:
function solution(A) {
// write your code in JavaScript (Node.js 8.9.4)
let missingNumber = A.length + 1;
// Sum up 1+2+3+...+N+(N+1) AND all of A[i] (except value not present in A[i] obviously). The value not present in A[i] is the odd one out. Note `missingNumber` starts with `A.length + 1` (i.e. N+1) because we loop N times here only...
for(let i = 0; i < A.length; ++i) {
missingNumber ^= (i + 1) ^ A[i];
}
return missingNumber;
}
https://florian.github.io/xor-trick/ has a good guide to understanding XORs.
Basically taking the idea where X ^ X equals 0, we use this to take advantage of duplicate values that cancels out the values so we get the non-duplicated value out (i.e. the missing element left).
This works because the question constraints guarantees the elements of A are all distinct. So we can just XOR them up together to take advantage of this trick. If this is a permutation where elements can be duplicated, this does not work, i.e. PermCheck
My solution tries to half the time of the summation. Detected time complexity:
O(N) or O(N * log(N))
`
int sumArray = 0;
int t = A.length-1;
for (int i=0; i<= t-i; i++) {
if(i == t-i){
sumArray += A[i];
break;
}
sumArray += (A[i] + A[t-i]);
}
int n = (A.length + 1);
int total = BigDecimal.valueOf(n).pow(2).add(BigDecimal.valueOf(n)).divide(BigDecimal.valueOf(2)).intValue();
return total - sumArray;
`
I just tried this solution which has no sorting and just sticks to the basics, got 100% result
public int solution100percent(int[] A) {
if (A.length == 0)
return 1;
int arrayCount = 0;
int iCount = 0;
for (int i = 0; i < A.length; i++) {
arrayCount += A[i];
iCount += i;
}
return iCount + A.length + (A.length + 1) - arrayCount;
}
Although knowing the total sum of consecutive integers would help get a fast solution , a fast but not memory efficient solution is possible using additional array and 2O(N) complexity without calculating the sum..
here is my solution:
class Solution {
public int findFalse(boolean [] ar){
for (int j = 0; j<ar.length; ++j){
if(ar[j]==false){
return j;
}
}
return -1;
}
public int solution(int[] A) {
// write your code in Java SE 8
boolean [] M = new boolean[A.length+1];
for (int i:A){
M[i-1] = true;
}
int missingValue = findFalse(M) +1 ;
return missingValue;
}
}

What should be the optimal way of solving Recurrence relation for really Huge number greater than Integer maximum value

I want to find the Nth number of the Recurrence Equation
T(n)=T(n-1)+3T(n-2)+3T(n-3)+(n-4),T(1)=T(4)=1,T(2)=T(3)=3
so if suppose you entered 2,5,9 as input, output should be T(2)=3,T(5)=20,T(9)=695
what I did is create an array of size equal to maximum of all input value and storing solution of T(i) at index i.Then look up into the array for specific index. eg array[3] for T(3),array[5] for T(5),etc
The code worked fine till maximum number is not greater than maximum integer value system can hold i.e
Integer.MAXValue.
Because the index of array can only be integer then
if number is n=1855656959555656 what should be the best way to find the solution of
T(1855656959555656)?
as clearly I cant create an array of size=1855656959555656..
I have even tried BigInteger from java.Math but with no success.
I have to find some other approach.please suggest some ideas..
Thanks
you do not need to store every T(i), you only need to store 3 values T(i-1), T(i-2), T(i-3). While looping over i, check if the current i should be part of your output, if so put it out immediately or save it to an "output"-array.
edit: this part is quite inefficient. You check in every iteation EVERY needed output.
for (int k = 0; k < arr.length; ++k) {
if (count == arr[k])
T[k] = temp[i];
else if (arr[k] == 1)
T[k] = 1;
else if (arr[k] == 2)
T[k] = 3;
else if (arr[k] == 3)
T[k] = 3;
else if (arr[k] == 4)
T[k] = 1;
}
so your code runs in time (max*arr.length) you can reduce it to only (max). Use a HashMap with key=neededPosition (=count) value=position in arr
Init the map like this:
Map<Long, Integer> map = new HashMap<Long, Integer>();
for (int i = 0; i < arr.length; i++) {
map.put(arr[i], i);
}
if (map.containsKey(count)) {
T[map.get(count)] = temp[i]
}
check the values 1-4 just once after the whole thing!
Not possible. The array size can be a maximum of Integer.MAX_VALUE (minus something usually 5 or 8, depending on the JVM capabilities). Why?. The index for an Array should be an integer thats a limitation.
It can't be done. So you need to solve the problem by introducing a sharding mechanism. The simplest way would be to just have arrays of arrays with a fixed length.
Edit: You really do not need this much storage for your problem at hand (as pointed out in another answer; this code fragment avoids arrays altogether to avoid bounds checks / indirection):
public void t(long n) {
if (n < 5) {
return (n == 2 || n == 3) ? 3 : 1;
}
long i = 5; // Initialize variables for n == 5;
long tn_1 = 1; // T(n-1) = T(4) = 1;
long tn_2 = 3; // T(n-2) = T(3) = 3;
long tn_3 = 1; // T(n-3) = T(2) = 1;
long tn_4 = 3; // T(n-4) = T(1) = 3;
while (true) {
long tn = tn_1 + 3*tn_2 + 3*tn_3 + tn_4;
if (i++ == n) {
return tn;
}
tn_4 = tn_3;
tn_3 = tn_2;
tn_2 = tn_1;
tn_1 = tn;
}
}
To answer the question in the title anyway:
If your array is sparse, use a map (TreeMap or HashMap) of Long or BigInteger:
Map<Long,Long> t = new TreeMap<Long,Long>()
The memory consumption of sparse arrays depends on the number of elements actually stored, so you may want to delete values from the map that are no longer needed.
If your array is not sparse, use a 2-level array (memory consumption will depend on the pre-allocated size only):
public class LongArray {
static final long BLOCK_SIZE = 0x40000000;
long[][] storage;
public LongArray(long size) {
long blockCount = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
storage = new long[][(int) blockCount];
for (long i = 0; i < blockCount; i++) {
if (i == blockCount - 1) {
storage[i] = new long[(int) size - BLOCK_SIZE * (blockCount - 1)];
} else {
storage[i] = new long[(int) BLOCK_SIZE];
}
}
}
public long get(long index) {
return storage[(int) (index / BLOCK_SIZE)][(int) (index % BLOCK_SIZE)];
}
public void put(long index, long value) {
storage[(int) (index / BLOCK_SIZE)][(int) (index % BLOCK_SIZE)] = value;
}
}
In both cases, use t.get(index) and t.put(index, value) instead of t[index] to access your array (if t is the name of the array).
You can do one thing. Check if the value of n is equal to 1855656959555656 in the beginning or if its multiple. Suppose, the value of n is twice of 1855656959555656. Then you can create two arrays and link them together virtually. This should solve your problem but it will involve a lot of overhead.
Use recursive call:
int T(int n){
if (n==1 || n==4){
return 1;
} else if (n==2 || n==3){
return 3;
} else {
return T(n-1)+3*T(n-2)+3T*(n-3)+T(n-4);
}
}
Edit: Time consumming. Won't work with large numbers

Efficient method to find the second largest even int in an array

The assignment is to create a method that finds the second largest even int in an array of ints. I am restricted from using any methods from any libraries.
Here is my code that works for all cases:
public static int getSecondLargestEven(int[] ary) {
int i;
aryLength = ary.length;
int largestEven = -1;
int secondLargestEven = -1;
for (i = 0; i < aryLength; i++) {
if (ary[i] % 2 == 0) {
if (ary[i] > largestEven) {
if (largestEven != -1)
secondLargestEven = largestEven;
largestEven = ary[i];
} else {
if (ary[i] != largestEven) {
if (secondLargestEven == -1 || ary[i] >= secondLargestEven) {
secondLargestEven = ary[i];
}
}
}
}
}
Prior to calling the methodI require the array to have more than one even else no method call.
So, when secondLargestEven == -1, I know there is a duplicate.
Is there a more efficient (less use of operators, less loops used, less memory allocation) way to accomplish the objective? How can I improve the logic of my code? How can I improve my code overall?
I don't like that I have to assign the magic number -1 to secondLargestEven and largestEven because they are technically named to hold EVENS. Would it be efficient to use a loop to assign a valid even integer in the array to both secondLargestEven and largestEven and THEN proceed to search? Thanks in advance.
You can make the code cleaner by not explicitly checking for the case when the largest and second variables are equal to -1.
Just set these variables to Integer.MIN_VALUE before the loop - this is the same as assuming that there were two additional values in your array that come before all the others, and they both have the value Integer.MIN_VALUE.
public static int secondLargestEven(int[] x) {
int largest = Integer.MIN_VALUE;
int second = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 == 0) {
if (x[i] > largest) {
second = largest;
largest = x[i];
} else if (x[i] > second) {
second = x[i];
}
}
}
return second;
}
Edit -- I thought I'd throw in that you can remove one level of nesting by using a continue statement inside the loop to skip the cases where you have an odd integer, although some people would consider this more difficult to understand than the code above.
It's a tradeoff - you use explicit control flow inside the loop (bad) but you remove a nesting level (good).
public static int secondLargestEven(int[] x) {
int largest = Integer.MIN_VALUE;
int second = Integer.MIN_VALUE;
for (int i = 0; i < x.length; i++) {
if (x[i] % 2 != 0)
continue;
if (x[i] > largest) {
second = largest;
largest = x[i];
} else if (x[i] > second)
second = x[i];
}
}
return second;
}
Just a fun thought... in Haskell, this function can be written in one line
import Data.List (sort)
secondLargestEven = (!! 1) . reverse . sort . filter even
or, if you want to be more efficient
import Data.List (sortBy)
import Data.Ord (comparing)
secondLargestEven = (!! 1) . sortBy (comparing negate) . filter even
This is just-for-fun implementation:
public static int secondLargestEven(int[] array) {
Set<Integer> evenSet = new TreeSet<>(Collections.reverseOrder());
for (int n : array) if (n % 2 == 0) evenSet.add(n);
return new ArrayList<>(evenSet).get(1);
}
This method is extremely inefficient (I cant look at it) but returns second largest even number :)
Method works only if array has second largest even number.

How to re-sort already sorted array where one element updates

I have array with constant size (size = 20 in real life), duplicates are allowed For example:
1 2 2 3 3 4 5 6 7 8 9
Now exactly one element updates:
1 5 2 3 3 4 5 6 7 8 9
I need to resort this array. Should I just use bubblesort?
update I don't know how to call what I wrote. But i suppose it is not possible to sort faster. comments are welcome!
// array is already almost sorted and INCREASING, element at pos need to be inserted to the right place
private void SortQuotes(List<Quote> quoteList, int pos)
{
var quoteToMove = quoteList[pos];
if (pos == 0 || quoteList[pos - 1].Price < quoteToMove.Price)
{
MoveElementsDown(quoteList, pos);
} else if (pos == quoteList.Count - 1 || quoteList[pos + 1].Price > quoteToMove.Price)
{
MoveElementsUp(quoteList, pos);
}
}
private void MoveElementsDown(List<Quote> quoteList, int pos)
{
var quoteToInsert = quoteList[pos];
var price = quoteToInsert.Price;
for (int i = pos - 1; i >= 0; i--)
{
var nextQuote = quoteList[i];
if (nextQuote.Price > price)
{
quoteList[i + 1] = quoteList[i];
if (i == 0) // last element
{
quoteList[i] = quoteToInsert;
}
}
else
{
quoteList[i + 1] = quoteToInsert;
break;
}
}
}
private void MoveElementsUp(List<Quote> quoteList, int pos)
{
var quoteToInsert = quoteList[pos];
var price = quoteToInsert.Price;
for (int i = pos + 1; i < quoteList.Count; i++)
{
var nextQuote = quoteList[i];
if (nextQuote.Price < price)
{
quoteList[i - 1] = quoteList[i];
if (i == quoteList.Count - 1) // last element
{
quoteList[i] = quoteToInsert;
}
}
else
{
quoteList[i - 1] = quoteToInsert;
break;
}
}
}
updated i do know which element is odd, i.e. it's position is known!
This solution shifts each element by one until the right position for the odd element is found. As it has been overwritten already in the first step, it is saved in a temporary variable 'h' and then written to the final position. It requires the minimum of comparisions and shift operations:
static void MoveOddElementToRightPosition(int[] a, int oddPosition)
{
int h = a[oddPosition];
int i;
if (h > a[oddPosition + 1])
for (i = oddPosition; i < a.Count()-1 && a[i+1] <= h; i++)
a[i] = a[i+1];
else
for (i = oddPosition; i > 0 && a[i-1] >= h; i--)
a[i] = a[i - 1];
a[i] = h;
}
Bubblesort will use n^2 time if the last element needs to get to the front. Use insertion sort.
As the array is small, insertion sort takes roughly ~O(n) time for small arrays and if you are just updating 1 value, insertion sort should fulfil your purpose in the best possible way.
It can be done in O(n). If you don't know the element then search for the element in O(n) and then You just need to compare and swap for each element and that would take O(n). So total 2n which means O(n).If you know the element which has been modified then compare and swap for each element.
If you're interested in replacing an element quickly, then you can also use a structure where deletion and insertion is fast, like for example a TreeSet in Java. That means O(log(n)) theoretically, but if you just manipulate arrays of 20 elements it may not be worth it
If the set of all different elements is finite, like in your example where you just use numbers for 1 to 9, then there is a solution in O(1). Instead of having a sorted list you just keep an array with the number of occurrences of your elements.
If you still want to keep everything in an array, then the fastest way is this
find the position A of of the element you're going to remove by bisection in O(log(n)).
find the position B of where your new element is going to end up in the same way. More precisely B is the smallest index where new_element < a[k] for every k > B
if A < B, move all elements between A + 1 and B to their left, then set the new element to position B. if B > A, you do the same thing but to the right. Now this step is in O(n), but there's no logic, it's just moving memory around. In C you'd use memmove for this and it's heavily optimized, but I don't know any Java equivalent.
You don't need to sort it again.
Only one element changes. So you just need to go through the list and put the changed number to appropriate place. This will be of O(n) complexity.
int a[] = {1, 5, 2, 3, 3, 4, 5, 6, 7, 8, 9};
int count = 0;
//find the odd element
for(int jj=1; jj< a.length; jj++){
if(a[jj] < a[count])
break;
else count++;
}
System.out.println(" Odd position " + count);
//put odd element to proper position
for(int k= count+1; k<a.length; k++){
if(a[count] > a[k]){
int t = a[count];
a[count] = a[k];
a[k] = t;
count++;
}
}
Above is the working code tested for given input.
Enjoy.
Bubblesort is quite OK in this case with 20 compares max.
But finding the new position with binary search is O(log(n)), that is 5 compares in this case.
Somewhat faster, if you need the last bit odd speed use the binary search otherwise you can stick with bubble sort.
Here is a naive implementation in plain C. Remove the fprintf(stderr, ... after testing. The ITEM can be anything, as long as a comparison function is possible. Otherwise: use pointers to ITEM, (and maybe add an extra sizeofelem argument, ala qsort)
#include <stdio.h>
#include <string.h>
typedef int ITEM;
int item_cmp(ITEM one, ITEM two);
unsigned one_bubble( ITEM *arr, unsigned cnt, unsigned hot , int (*cmp)(ITEM,ITEM) );
int item_cmp(ITEM one, ITEM two)
{
fprintf(stderr,"Cmp= %u to %u: %d\n", one, two, one-two);
if (one > two) return 1;
else if (one < two) return -1;
else return 0;
}
unsigned one_bubble( ITEM *arr, unsigned cnt, unsigned hot , int (*cmp)(ITEM,ITEM) )
{
unsigned goal = cnt;
int diff;
ITEM temp;
/* hot element should move to the left */
if (hot > 0 && (diff=cmp( arr[hot-1], arr[hot])) > 0) {
/* Find place to insert (this could be a binary search) */
for (goal= hot; goal-- > 0; ) {
diff=cmp( arr[goal], arr[hot]);
if (diff <= 0) break;
}
goal++;
fprintf(stderr,"Move %u LEFT to %u\n", hot, goal);
if (goal==hot) return hot;
temp = arr[hot];
/* shift right */
fprintf(stderr,"memmove(%u,%u,%u)\n", goal+1, goal, (hot-goal) );
memmove(arr+goal+1, arr+goal, (hot-goal) *sizeof temp);
arr[goal] = temp;
return goal; /* new position */
}
/* hot element should move to the right */
else if (hot < cnt-1 && (diff=cmp( arr[hot], arr[hot+1])) > 0) {
/* Find place to insert (this could be a binary search) */
for (goal= hot+1; goal < cnt; goal++ ) {
diff=cmp( arr[hot], arr[goal]);
if (diff <= 0) break;
}
goal--;
fprintf(stderr,"Move %u RIGHT to %u\n", hot, goal);
if (goal==hot) return hot;
temp = arr[hot];
/* shift left */
fprintf(stderr,"memmove(%u,%u,%u)\n", hot, hot+1, (goal-hot) );
memmove(arr+hot, arr+hot+1, (goal-hot) *sizeof temp);
arr[goal] = temp;
return goal; /* new position */
}
fprintf(stderr,"Diff=%d Move %u Not to %u\n", diff, hot, goal);
return hot;
}
ITEM array[10] = { 1,10,2,3,4,5,6,7,8,9,};
#define HOT_POS 1
int main(void)
{
unsigned idx;
idx = one_bubble(array, 10, HOT_POS, item_cmp);
printf("%u-> %u\n", HOT_POS, idx );
for (idx = 0; idx < 10; idx++) {
printf("%u: %u\n", idx, array[idx] );
}
return 0;
}

Categories