Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
Assignment - Write two Java programs!
The first one uses a recursive algorithm.
The second one uses a non-recursive algorithm.
They must determine if a list (of any length) has the following pattern:
Cell[0] = 2;
Cell[1] = 2squared = 4;
Cell[3] = 4squared = 16;
The pattern is where any value of a cell [n+1] is equal to the square of the value in cell[n].
e.g: 2, 4, 16, 256, 65536, 4294967296
Question:
Can anyone point me to a code example, please?
Thanks in advance!
Here is one way to do it using BigInteger. But even then, I limited the number of terms to 8 as they get quite large.
Iterative call.
BigInteger[] terms = iterative(8);
for (BigInteger b : terms) {
System.out.println(b);
}
System.out.println("Sequence array for iteration is " +
(validate(terms) ? "valid" : "invalid"));
Prints
2
4
16
256
65536
4294967296
18446744073709551616
340282366920938463463374607431768211456
Sequence array for iterative is valid
Recusive call
terms = recursive(8);
for (BigInteger b : terms) {
System.out.println(b);
}
System.out.println("Sequence array for recursion is " +
(validate(terms) ? "valid" : "invalid"));
Prints
2
4
16
256
65536
4294967296
18446744073709551616
340282366920938463463374607431768211456
Sequence array for recursion is valid
Validation method
public static boolean validate(BigInteger[] terms) {
for (int i = 1; i < terms.length; i++) {
if (!terms[i].equals(terms[i-1].pow(2))) {
return false;
}
}
return true;
}
The iterative approach.
simply initialize the first term to Biginteger.TWO.
then iterate over the list raising each previous term to the power of 2.
public static BigInteger[] iterative(int n) {
if (n < 1) {
throw new IllegalArgumentException("n must be > 0");
}
BigInteger[] terms = new BigInteger[n];
terms[0] = BigInteger.TWO; // 2^2^0 = 2;
for (int i = 1; i < n; i++) {
terms[i] = terms[i-1].pow(2);
}
return terms;
}
The recursive approach.
Although it can be done without a helper method using one is more straightforward and efficient.
allocate the array based on n
initialize the 0th element to 2.
return immediately if n == 1
otherwise, invoke the helper method.
public static BigInteger[] recursive(int n) {
if (n < 1) {
throw new IllegalArgumentException("n must be > 0");
}
BigInteger[] terms = new BigInteger[n];
terms[0] = BigInteger.TWO;
if (n == 1) {
return terms;
}
return recursiveHelper(terms, n);
}
recursively call the method until n == 2
then simply assign the n-1 element the value in n-2 raised to the power of 2
then return the terms.
private static BigInteger[] recursiveHelper(BigInteger[] terms, int n) {
if (n > 2) {
recursiveHelper(terms,n-1);
}
terms[n-1] = terms[n-2].pow(2);
return terms;
}
There is no specific algorithm for this problem that I know of, but here are code examples:
Recursive:
public boolean validSequenceFromIndex(int[] sequence, int index) {
if (index >= sequence.length - 1) return true; // If it is the last index or
// greater, then it works.
if (sequence[index + 1] != sequence[index] * sequence[index]) return false; // The
// pattern does not hold.
return validSequenceFromIndex(sequence, index + 1); // The sequence is valid at this
// index, check the rest of the sequence.
}
Notice here that the parameters here are an int[] sequence and an int index while the problem should only give you an int[] sequence. Simply write a function like the following:
public boolean validSequence(int[] sequence) {
return validSequenceFromIndex(sequence, 0); // Checks if the sequence is valid starting
// from the beginning (essentially the whole sequence.
}
which should transfer only having the sequence as a parameter to using a sequence and an index.
Non-recursive:
public boolean validSequence(int[] sequence) {
for (int i = 0; i < sequence.length - 1; i++) { // Loop through entirety of the
// except for the last index.
if (sequence[i + 1] != sequence[i] * sequence[i]) return false;
}
// All indices checked, the sequence works:
return true;
}
Hope this made sense to you!
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;
}
}
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
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.
we got a matrix size of NxN which is represented by a multidimentional array, the matrix contains integer numbers, we assume that N=2^K.
We can also say that the matrix is ordered by cutting the matrix to 4 quarters (image below), every element in the first quarter is smaller or equal to the element in the second quarter, every element in the second quarter is smaller or equal to the third quarter, and every element in the third quarter is smaller or equal to every element in the forth quarter. (and so on recursivly)
like this:
1 2
3 4
Example of sorted matrix:
We need to write a function that returns true if the num exist in the matrix.
and to make it as most efficient as possible.
I've wrote the following function:
public static boolean isExist(int[][] mat, int num)
{
int start_rows = 0;
int start_columns = 0;
// If more then 4 elements
// Loop log(base 4)n
for (int elements_size = mat.length * mat[0].length, table_size, quarter_size,
quarter1, quarter2, quarter3, quarter4;
(elements_size > 4);
elements_size /= 4)
{
table_size = (int)(Math.sqrt(elements_size));
quarter1 = mat[start_rows+(table_size/2)-1][start_columns+(table_size/2)-1];
quarter2 = mat[start_rows+(table_size/2)-1][start_columns+table_size-1];
quarter3 = mat[start_rows+table_size-1][start_columns+(table_size/2)-1];
quarter4 = mat[start_rows+table_size-1][start_columns+table_size-1];
if (num == quarter1 || num == quarter2 || num == quarter3 || num == quarter4) {
return true;
}
// Decrease elements_size
quarter_size = (int)Math.sqrt(elements_size/4);
if (quarter1 > num) {
// Dont do anything
} else if (quarter2 > num) {
start_columns += quarter_size; // Increase columns
} else if (quarter3 > num) {
start_rows += quarter_size; // Increase rows
} else if (quarter4 > num) {
start_rows += quarter_size; // Increase rows
start_columns += quarter_size; // Increase columns
} else {
return false; // bigger then quarter, fail.
}
}
return (mat[start_rows][start_columns] == num || mat[start_rows+1][start_columns] == num ||
mat[start_rows][start_columns+1] == num || mat[start_rows+1][start_columns+1] == num);
}
Is that the most efficient way to do so?
Also its time complexity is O(logn). (am I correct?)
well, that is a good approach!
if i understood you right, you want to find out if the array includes a specific int-value;
well, i would use the following methode (but you have to match this to a int [][] array):
HashSet<Integer> test= new HashSet<Integer>(Arrays.asList(intArray));
test.contains(intValue)
this approach is pretty fastest because the hashcode-mechanism has the complexity O(1) but i think through the asList()- it leads to arraylist complexity O(n)... not sure about this!!
It can be done in time complexity O(n). I am not sure if the post is still active. But below is my solution to do it in O(n).
public class NumberInMatrix {
public static void main(String args[]){
int matrix[][] = {{-4,-2,5,9},
{2,5,12,13},
{13,20,25,25},
{22,24,49,57},};
System.out.println(isExist(matrix, 1));
}
private static String isExist(int[][] matrix, int numberToBeSearched) {
int rowCounter = 0, colCounter = matrix[0].length - 1;
while(rowCounter < matrix.length && colCounter >= 0){
if(numberToBeSearched == matrix[rowCounter][colCounter]){
return "Number exist";
}else{
if(numberToBeSearched > matrix[rowCounter][colCounter]){
rowCounter++;
}else{
colCounter--;
}
}
}
return "Number does not exist";
}
}