I am trying to get the biggest and second biggest distance in a Hashmap in Java.
Basically, from a hashmap populated with (x,y) values, I plan to pick a point, set it as a fixed point and calculate distance with this point in relation to all the other points. After all possible distances are calculated, I change the fixed point to the next element in the HashMap. With this process, I aim to get the biggest and second biggest value in a hashmap distance-wise.
HashMap<Integer, Integer> corners = getPotentialCorners(image);
HashMap<Integer, Integer> extremeCorners = new HashMap<>();
int Blue = new Color(0, 0, 255).getRGB();
int currentNumberX;
int currentNumberY;
int pivotVarX;
int pivotVarY;
double distance;
double Highest = 0;
double Highest2 = 1;
int xHighest = 0;
int yHighest = 0;
int xHighest2 = 0;
int yHighest2 = 0;
for (int i : corners.keySet()) {
currentNumberX = (i);
currentNumberY = corners.get(currentNumberX);
for (int j : corners.keySet()) {
pivotVarX = j;
pivotVarY = corners.get(pivotVarX);
distance = Math.abs(Math.sqrt(Math.pow((pivotVarX - currentNumberX), 2) + Math.pow((pivotVarY - currentNumberY), 2)));
if (pivotVarX != currentNumberX) {
if ((Highest > Highest2)) {
xHighest = currentNumberX;
yHighest = currentNumberY;
Highest2 = distance;
}
if (distance > Highest2) {
Highest2 = distance;
xHighest2 = currentNumberX;
yHighest2 = currentNumberY;
}
}
}
}
With this code, I debugged it, and I always get one correct point, and another point is ALWAYS (0,0). I know the issue lies with my process of getting the second highest point (Highest2, XHighest2,YHighest2), but I do not know how to fix it.
As others pointed out, instead of a HashMap, it is better to use List<Point> which you can easily iterate as:
for (Point p: myList) {
...
}
or if you need more control on which elements to iterate over you can use an integer counter:
for (int j = i+1; j < corners.size(); j++) {
Point p = corners.get(j);
...
}
instead of having to use keySet() and get() and all the problems with identical x-values mapping on the same bin.
Also, there are some trivial speed improvements possible:
No need to use the slow Math.sqrt() function (or Math.abs() as square root is always positive) since you are only comparing larger/smaller distances. You can just compare the squared distances.
The latest Java compiler knows how to optimize Math.pow(int, 2), but to make sure you don't get the overhead of a function call, you can help the compiler by writing: (p.x-q.x)*(p.x-q.x) + (p.y-q.y)*(p.x-q.y)
Renaming current and pivot to p and q for conciseness, your code would look like:
List<Point> corners = getPotentialCorners(image);
Double highest = null;
Double highest2 = null;
Point highestP = null, highestQ = null;
Point highestP2 = null, highestQ2 = null;
for (int i = 0; i < corners.size()-1; i++) {
Point p = corners.get(i);
for (int j = i+1; j < corners.size(); j++) {
Point q = corners.get(j);
double distanceSq = (p.x-q.x)*(p.x-q.x) + (p.y-q.y)*(p.y-q.y);
if (highest == null || distanceSq >= highest) {
// shift highest to second highest
highest2 = highest;
highestP2 = highestP;
highestQ2 = highestQ;
highest = distanceSq;
highestP = p;
highestQ = q;
} else if (highest2 == null || distanceSq > highest2) {
highest2 = distanceSq;
highestP2 = p;
highestQ2 = q;
}
}
}
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;
}
I'm trying to test implementations of Prim's and Kruskal's algorithm by using a cost adjacency matrix. I'm generating these matrices on the amount of vertices in the graph, and the amount of edges in the graph. It does not have to be a connected graph.
Here's what I have so far:
final static int infinity = 2000000000;
public static int[][] genAdjMat(int V, int E) {
int[][] a = new int[V][V];
int e = E;
for(int i = 0; i < V; i++) {
for(int j = i; j < V; j++) {
if(i == j) {
a[i][j] = 0;
}
else {
if(Math.random() < 0.5 && e >= 0) {
int temp = (int)Math.ceil(Math.random()*e);
a[i][j] = temp;
a[j][i] = temp;
e--;
}
else {
a[i][j] = infinity;
a[j][i] = infinity;
}
}
}
}
return a;
}
Right now, it generates a symmetric array but it doesn't use all the edges that I specify. I'm having trouble figuring out how to use up all the edges and still have them randomly placed throughout the matrix while maintaining symmetry.
I'd suggest the following:
Generate the list of all possible undirected edges (V * (V - 1) / 2 items).
Shuffle it.
Pick the first E edges.
Straight forward: just generate the edges independently.
Random random = new Random();
Set<Map.Entry<Integer,Integer>> edges = Sets.newHashSet();
for (int i=0; i<e; i++) {
do {
int xCoordinate = random.nextInt(V);
int yCoordinate = random.nextInt(V);
} while(!edges.add(xCoordinate, yCoordinate));
}
Now use the edges to put them in your matrix.
Alternatively (while iterating over the matrix), use the following probability function: p(A[i,j] == 1) = (e - k) / (V^2 - (i * V + j)). Where k is the number of already assigned edges. The point of this is - have a probability less then 1 while the number of entries that are remaining is still higher then the number of edges you have to assign, this becomes 1 when the number of edges you still have to assign is equal to remaining entries to iterate over.
During a 45 minute technical interview with Google, I was asked a Leaper Graph problem.
I wrote working code, but later was declined the job offer because I lacked Data structure knowledge. I'm wondering what I could have done better.
The problem was as following:
"Given an N sized board, and told that a piece can jump i positions horizontally (left or right) and j positions vertically (up or down) (I.e, sort of like a horse in chess), can the leaper reach every spot on the board?"
I wrote the following algorithm. It recursively finds out if every position on the board is reachable by marking all spots on the graph that were visited. If it was not reachable, then at least one field was false and the function would return false.
static boolean reachable(int i, int j, int n) {
boolean grid[][] = new boolean[n][n];
reachableHelper(0, 0, grid, i, j, n - 1);
for (int x = 0; x < n; x++) {
for (int y = 0; y < n; y++) {
if (!grid[x][y]) {
return false;
}
}
}
return true;
}
static void reachableHelper(int x, int y, boolean[][] grid, int i, int j, int max) {
if (x > max || y > max || x < 0 || y < 0 || grid[x][y]) {
return;
}
grid[x][y] = true;
int i2 = i;
int j2 = j;
for (int a = 0; a < 2; a++) {
for (int b = 0; b < 2; b++) {
reachableHelper(x + i2, y + j2, grid, i, j, max);
reachableHelper(x + j2, y + i2, grid, i, j, max);
i2 = -i2;
}
j2 = -j2;
}
}
Now, later it was pointed out that the optimal solution would be to implement Donald Knuth's co-prime implementation:
http://arxiv.org/pdf/math/9411240v1.pdf
Is this something that one should be able to figure out on a 45 minute technical interview??
Besides the above, is there anything I could have done better?
edit:
- I enquired about starting position. I was told starting at 0,0 is fine.
edit2
Based on feedback, I wrote a while-loop with queue approach.
The recursive approach runs into a stack-overflow when n = 85.
However, the while loop with queue method below works up to ~n = 30,000. (after that it runs into heap-issues with memory exceeding GB's). If you know how to optimize further, please let me know.
static boolean isReachableLoop(int i, int j, int n) {
boolean [][] grid = new boolean [n][n];
LinkedList<Point> queue = new LinkedList<Point>();
queue.add(new Point(0,0)); // starting position.
int nodesVisited = 0;
while (queue.size() != 0) {
Point pos = queue.removeFirst();
if (pos.x >= 0 && pos.y >= 0 && pos.x < n && pos.y < n) {
if (!grid[pos.x][pos.y]) {
grid[pos.x][pos.y] = true;
nodesVisited++;
int i2 = i;
int j2 = j;
for (int a = 0; a < 2; a++) {
for (int b = 0; b < 2; b++) {
queue.add(new Point(pos.x+i2, pos.y+j2));
queue.add(new Point(pos.x+j2, pos.y+i2));
i2 = -i2;
}
j2 = -j2;
}
}
}
}
if (nodesVisited == (n * n)) {
return true;
} else {
return false;
}
}
I ask a lot of interview questions like this. I don't think you would be expected to figure out the coprime method during the interview, but I would have docked you for using O(n^2) stack space -- especially since you passed all those parameters to each recursive call instead of using an object.
I would have asked you about that, and expected you to come up with a BFS or DFS using a stack or queue on the heap. If you failed on that, I might have a complaint like "lacked data structure knowledge".
I would also have asked questions to make sure you knew what you were doing when you allocated that 2D array.
If you were really good, I would ask you if you can use the symmetry of the problem to reduce your search space. You really only have to search a J*J-sized grid (assuming J>=i).
It's important to remember that the interviewer isn't just looking at your answer. He's looking at the way you solve problems and what tools you have in your brain that you can bring to bear on a solution.
Edit: thinking about this some more, there are lots of incremental steps on the way to the coprime method that you might also come up with. Nobody will expect that, but it would be impressive!
I'm sorry, I feel like I'm missing something.
If you can only go up or down by i and left or right by j, then a case (x,y) is reachable from a start case (a,b) if there are integers m and n so that
a + m*i = x
b + n*j = y
That is, everything is false for a square board where n > 1.
If you meant more like a knight in chess, and you can go up/down by i and left/right by j OR up/down by j and left/right by i, you can use the same technique. It just becomes 2 equations to solve:
a + m * i + n * j = x
b + o * i + p * j = y
If there are no integers m, n, o and p that satisfy those equations, you can't reach that point.
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;
}
}