Related
I have a Google foobar challenge:
Write a function called answer(data, n) that takes in a list of less than 100 integers and a number n, and returns that same list but with all of the numbers that occur more than n times removed entirely. The returned list should retain the same ordering as the original list - you don't want to mix up those carefully-planned shift rotations! For instance, if data was [5, 10, 15, 10, 7] and n was 1, answer(data, n) would return the list [5, 15, 7] because 10 occurs twice, and thus was removed from the list entirely.
And this was my answer:
public static int[] solution(int[] data, int n) {
// Your code here
int count,c=0;
int flag[]=new int[1000];
int b[]=new int[data.length];
for(int i=0;i<data.length;i++)
{ count=0;
if(flag[(data[i])]==0)
{
for(int j=0;j<data.length;j++)
{
if(data[i]==data[j])
count++;
}
if(count>n)
flag[(data[i])]=1;
else
{
flag[(data[i])]=2;
b[c++]=data[i];
}
}
else if(flag[(data[i])]==2)
{
b[c++]=data[i];
}
}
if(c==(data.length))
{
return b;
}
if(c==0)
{
int ne[]=new int[0];
return ne;
}
else
{
int ne[]=new int[c];
for(int k=0;k<c;k++)
{
ne[k]=b[k];
}
return ne;
}
}
It passed 8 test cases but is failing for the last test case and I am not able to figure out what could the test case since that one is a hidden case. Any idea?
Generally, when trying to find a problem, you run tests. I made your code fragment into a class I could teat.
I formatted your code to see more clearly what you were doing. Using more descriptive variable names would help. Also, don't rely on single statements of an if or a for loop not needing braces. The first time you try to add a line of code, forgetting that you left off the braces, well good luck debugging that.
Here's the test class I created. I couldn't find anything after trying about two dozen different values of N and input.
import java.util.Arrays;
public class GoogleChallenge {
public static void main(String[] args) {
int[] data = { 5, 10, 15, 10, 7, 888, 999, 999, 0 };
int n = 1;
System.out.println("input: n: " + n + " " + Arrays.toString(data));
System.out.println("Output: " + Arrays.toString(solution(data, n)));
}
public static int[] solution(int[] data, int n) {
// Your code here
int count, c = 0;
int flag[] = new int[1000];
int b[] = new int[data.length];
for (int i = 0; i < data.length; i++) {
count = 0;
if (flag[(data[i])] == 0) {
for (int j = 0; j < data.length; j++) {
if (data[i] == data[j]) {
count++;
}
}
if (count > n) {
flag[(data[i])] = 1;
} else {
flag[(data[i])] = 2;
b[c++] = data[i];
}
} else if (flag[(data[i])] == 2) {
b[c++] = data[i];
}
}
if (c == (data.length)) {
return b;
}
if (c == 0) {
int ne[] = new int[0];
return ne;
} else {
int ne[] = new int[c];
for (int k = 0; k < c; k++) {
ne[k] = b[k];
}
return ne;
}
}
}
Given an array on numbers as input, remove all elements from the array which are either multiple of 3 or have the digit 3 in them. For e.g. 13 and 15 will be both removed from the array if they are present.
MyApproach
To remove 3, I have made function removeMultiple which first remove Multiple of 3 if it exist.And then I also made function removeDigit Which removes the digit 3 int it if the number is not multiple of 3.
But I am not getting expected output.
MyQuestion:What I am doing wrong in my code.Can anyone guide me?
#Edit:
boolean containsDigit3(int[] arr,int index)
{
boolean b1=false;
while(arr[index]>0)
{
int p=arr[index]%10;
if(p==3)
{
b1=true;
}
arr[index]=arr[index]/10;
}
if(b1==true)
return true;
else
return false;
}
boolean isMultipleOf3(int[] arr,int index)
{
boolean b1=false;
int p=arr[index]%3;
if(p==0)
{
b1=true;
}
if(b1==true)
return true;
else
return false;
}
public int[] remove(int[] arr)
{
// Array of max length
int p[] = new int[arr.length];
int count = 0;
for (int i = 0; i < arr.length; i++)
{
if (!isMultipleOf3(arr,i) && !containsDigit3(arr,i))
{
p[i] = arr[i];
++count;
}
}
// Array of right length - System.arraycopy not allowed?!
int[] q = new int[count];
for (int i = 0; i < q.length; ++i)
{
q[i] = p[i];
}
return q;
}
Parameters Actual Output Expected Output
'{24,27,30,31,34,37,40,42}' {0} {40}
Operating on full arrays might be more difficult than it has to be. Break down your code into small and accurate parts, don't mix up iterating and copying an array with checking-for-3-logic.
Consider this method to remove those unwanted elements:
public int[] remove(int[] arr) {
// Array of max length
int p[] = new int[arr.length];
int count = 0;
for (int i = 0; i < arr.length; i++) {
if (!isMultipleOf3(arr[i]) && !containsDigit3(arr[i])) {
p[count] = arr[i];
++count;
}
}
// Array of right length - System.arraycopy not allowed?!
int[] q = new int[count];
for (int i = 0; i < q.length; ++i) {
q[i] = p[i];
}
return q;
}
Now you can focus on very, very simple methods for boolean isMultipleOf3(int i) and boolean containsDigit3(int i)
Here's some very basic implementations:
private boolean containsDigit3(int i) {
//indexOf returns position of character '3' in String that
//represents the number i. If '3' is not found it returns -1
//so indexOf('3') >= 0 is another way of saying "contains digit 3"
return Integer.toString(i).indexOf('3') >= 0;
}
private boolean isMultipleOf3(int i) {
return i%3 == 0;
}
I would write it like this
public int[] remove(int[] arr) {
return IntStream.of(arr)
.filter(i -> i % 3 != 0)
.filter(i -> !(""+i).contains("3"))
.toArray();
}
I have to hard code it.No inbuilt functions allowed.
In that case I would do something like the above except "hard coded"
public static int[] remove(int[] arr) {
int[] ret = new int[arr.length];
int count = 0;
OUTER:
for (int i : arr) {
if (i % 3 == 0)
continue;
int j = i;
while (j > 0) {
if (j % 10 == 3)
continue OUTER;
j /= 10;
}
ret[count++] = i;
}
// do the same as Arrays.copyOf(ret, count)
if (ret.length > count) {
int[] ret2 = new int[count];
for (int i = 0; i < count; i++)
ret2[i] = ret[i];
return ret2;
}
return ret;
}
so
int[] arr = {24, 27, 30, 31, 34, 37, 40, 42};
int[] arr2 = remove(arr);
System.out.println(Arrays.toString(arr2));
prints
[40]
I have an array of integers, and I need to find the one that's closest to zero (positive integers take priority over negative ones.)
Here is the code I have so far:
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
near = data[i];
}
}
System.out.println( near );
}
}
Currently I'm getting a result of -2 but I should be getting 2. What am I doing wrong?
This will do it in O(n) time:
int[] arr = {1,4,5,6,7,-1};
int closestIndex = 0;
int diff = Integer.MAX_VALUE;
for (int i = 0; i < arr.length; ++i) {
int abs = Math.abs(arr[i]);
if (abs < diff) {
closestIndex = i;
diff = abs;
} else if (abs == diff && arr[i] > 0 && arr[closestIndex] < 0) {
//same distance to zero but positive
closestIndex =i;
}
}
System.out.println(arr[closestIndex ]);
If you are using java8:
import static java.lang.Math.abs;
import static java.lang.Math.max;
public class CloseToZero {
public static void main(String[] args) {
int[] str = {2,3,-2};
Arrays.stream(str).filter(i -> i != 0)
.reduce((a, b) -> abs(a) < abs(b) ? a : (abs(a) == abs(b) ? max(a, b) : b))
.ifPresent(System.out::println);
}
}
Sort the array (add one line of code) so the last number you pick up will be positive if the same absolute value is selected for a positive and negative numbers with the same distance.
Source code:
import java.util.Arrays;
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
Arrays.sort(data); // add this
System.out.println(Arrays.toString(data));
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
System.out.println("dist from " + data[i] + " = " + Math.abs(0 -data[i]));
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
near = data[i];
}
}
System.out.println( near );
}
}
Just add zero to this list.
Then sort the list
Arrays.sort(data);
then grab the number before or after the zero and pick the minimum one greater than zero
Assumption is that the array data has at least 1 value.
int closestToZero = 0;
for ( int i = 1; i < data.length; i++ )
{
if ( Math.abs(data[i]) < Math.abs(data[closestToZero]) ) closestToZero = i;
}
The value in closestToZero is the index of the value closest to zero, not the value itself.
static int Solve(int N, int[] A){
int min = A[0];
for (int i=1; i<N ; i++){
min = min > Math.abs(0- A[i]) ? Math.abs(0- A[i]) : Math.abs(min);
}
return min;
}
As you multiply data[i] with data[i], a value negative and a value positive will have the same impact.
For example, in your example: 2 and -2 will be 4. So, your code is not able to sort as you need.
So, here, it takes -2 as the near value since it has the same "weight" as 2.
I have same answer with different method,Using Collections and abs , we can solved.
static int Solve(int N, int[] A){
List<Integer> mInt=new ArrayList<>();
for ( int i=0; i < A.length; i++ ){
mInt.add(Math.abs(0 -A[i]));
}
return Collections.min(mInt);
}
That all,As simple as that
This is a very easy to read O(n) solution for this problem.
int bigestNegative = Integer.MIN_VALUE;
int smalestpositive = Integer.MAX_VALUE;
int result = 0;
for (int i = 0; i < n; i++) {
//if the zero should be considered as result as well
if ( temperatures[i] == 0 ) {
result = 0;
break;
}
if ( temperatures[i] > 0 && temperatures[i] < smalestpositive ) {
smalestpositive = temperatures[i];
}
if ( temperatures[i] < 0 && temperatures[i] > bigestNegative ) {
bigestNegative = temperatures[i];
}
}
if( (Math.abs(bigestNegative)) < (Math.abs(smalestpositive)) && bigestNegative != Integer.MIN_VALUE)
result = bigestNegative;
else
result = smalestpositive;
System.out.println( result );
First convert the int array into stream. Then sort it with default sorting order. Then filter greater than zero & peek the first element & print it.
Do it in declarative style which describes 'what to do', not 'how to do'. This style is more readable.
int[] data = {2,3,-2};
IntStream.of(data)
.filter(i -> i>0)
.sorted()
.limit(1)
.forEach(System.out::println);
using Set Collection and abs methode to avoid complex algo
public static void main(String[] args) {
int [] temperature={0};
***// will erase double values and order them from small to big***
Set<Integer> s= new HashSet<Integer>();
if (temperature.length!=0) {
for(int i=0; i<temperature.length; i++) {
***// push the abs value to the set***
s.add(Math.abs(temperature[i]));
}
// remove a zero if exists in the set
while(s.contains(0)) {
s.remove(0);
}
***// get first (smallest) element of the set : by default it is sorted***
if (s.size()!=0) {
Iterator iter = s.iterator();
System.out.println(iter.next());
}
else System.out.println(0);
}
else System.out.println(0);
}
static int nearToZero(int[] A){
Arrays.sort(A);
int ans = 0;
List<Integer> list = Arrays.stream(A).boxed().collect(Collectors.toList());
List<Integer> toRemove = new ArrayList<>();
List<Integer> newList = new ArrayList<>();
for(int num: list){
if(newList.contains(num)) toRemove.add(num);
else newList.add(num);
}
list.removeAll(toRemove);
for(int num : list){
if(num == 0 ) return 0;
if(ans == 0 )ans = num;
if(num < 0 && ans < num) ans = num;
if(num < ans) ans = num;
if(num > 0 && Math.abs(ans) >= num) ans = num;
}
return ans;
}
here is a method that gives you the nearest to zero.
use case 1 : {1,3,-2} ==> return 1 : use the Math.abs() for comparison and get the least.
use case 2 : {2,3,-2} ==> return 2 : use the Math.abs() for comparison and get the Math.abs(least)
use case 3 : {-2,3,-2} ==> return -2: use the Math.abs() for comparison and get the least.
public static double getClosestToZero(double[] liste) {
// if the list is empty return 0
if (liste.length != 0) {
double near = liste[0];
for (int i = 0; i < liste.length; i++) {
// here we are using Math.abs to manage the negative and
// positive number
if (Math.abs(liste[i]) <= Math.abs(near)) {
// manage the case when we have two equal neagative numbers
if (liste[i] == -near) {
near = Math.abs(liste[i]);
} else {
near = liste[i];
}
}
}
return near;
} else {
return 0;
}
}
You can do like this:
String res = "";
Arrays.sort(arr);
int num = arr[0];
int ClosestValue = 0;
for (int i = 0; i < arr.length; i++)
{
//for negatives
if (arr[i] < ClosestValue && arr[i] > num)
num = arr[i];
//for positives
if (arr[i] > ClosestValue && num < ClosestValue)
num = arr[i];
}
res = num;
System.out.println(res);
First of all you need to store all your numbers into an array. After that sort the array --> that's the trick who will make you don't use Math.abs(). Now is time to make a loop that iterates through the array. Knowing that array is sorted is important that you start to make first an IF statement for negatives numbers then for the positives (in this way if you will have two values closest to zero, let suppose -1 and 1 --> will print the positive one).
Hope this will help you.
The easiest way to deal with this is split the array into positive and negative sort and push the first two items from both the arrays into another array. Have fun!
function closeToZeroTwo(arr){
let arrNeg = arr.filter(x => x < 0).sort();
let arrPos = arr.filter(x => x > 0).sort();
let retArr = [];
retArr.push(arrNeg[0], arrPos[0]);
console.log(retArr)
}
Easiest way to just sort that array in ascending order suppose input is like :
int[] array = {10,-5,5,2,7,-4,28,65,95,85,12,45};
then after sorting it will gives output like:
{-5,-4,2,5,7,10,12,28,45,65,85,95,}
and for positive integer number, the Closest Positive number is: 2
Logic :
public class Closest {
public static int getClosestToZero(int[] a) {
int temp=0;
//following for is used for sorting an array in ascending nubmer
for (int i = 0; i < a.length-1; i++) {
for (int j = 0; j < a.length-i-1; j++) {
if (a[j]>a[j+1]) {
temp = a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
//to check sorted array with negative & positive values
System.out.print("{");
for(int number:a)
System.out.print(number + ",");
System.out.print("}\n");
//logic for check closest positive and Integer
for (int i = 0; i < a.length; i++) {
if (a[i]<0 && a[i+1]>0) {
temp = a[i+1];
}
}
return temp;
}
public static void main(String[] args) {
int[] array = {10,-5,5,2,7,-4,28,65,95,85,12,45};
int closets =getClosestToZero(array);
System.out.println("The Closest Positive number is : "+closets);
}
}
static void closestToZero(){
int[] arr = {45,-4,-12,-2,7,4};
int max = Integer.MAX_VALUE;
int closest = 0;
for (int i = 0; i < arr.length; i++){
int value = arr[i];
int abs = Math.abs(value);
if (abs < max){
max = abs;
closest = value;
}else if (abs == max){
if (value > closest){
closest = value;
}
}
}
Return a positive integer if two absolute values are the same.
package solution;
import java.util.Scanner;
public class Solution {
public static void trier(int tab[]) {
int tmp = 0;
for(int i = 0; i < (tab.length - 1); i++) {
for(int j = (i+1); j< tab.length; j++) {
if(tab[i] > tab[j]) {
tmp = tab[i];
tab[i] = tab[j];
tab[j] = tmp;
}
}
}
int prochePositif = TableauPositif(tab);
int procheNegatif = TableauNegatif(tab);
System.out.println(distanceDeZero(procheNegatif,prochePositif));
}
public static int TableauNegatif(int tab[]) {
int taille = TailleNegatif(tab);
int tabNegatif[] = new int[taille];
for(int i = 0; i< tabNegatif.length; i++) {
tabNegatif[i] = tab[i];
}
int max = tabNegatif[0];
for(int i = 0; i <tabNegatif.length; i++) {
if(max < tabNegatif[i])
max = tabNegatif[i];
}
return max;
}
public static int TableauPositif(int tab[]) {
int taille = TailleNegatif(tab);
if(tab[taille] ==0)
taille+=1;
int taillepositif = TaillePositif(tab);
int tabPositif[] = new int[taillepositif];
for(int i = 0; i < tabPositif.length; i++) {
tabPositif[i] = tab[i + taille];
}
int min = tabPositif[0];
for(int i = 0; i< tabPositif.length; i++) {
if(min > tabPositif[i])
min = tabPositif[i];
}
return min;
}
public static int TailleNegatif(int tab[]) {
int cpt = 0;
for(int i = 0; i < tab.length; i++) {
if(tab[i] < 0) {
cpt +=1;
}
}
return cpt;
}
public static int TaillePositif(int tab[]) {
int cpt = 0;
for(int i = 0; i < tab.length; i++) {
if(tab[i] > 0) {
cpt +=1;
}
}
return cpt;
}
public static int distanceDeZero(int v1, int v2) {
int absv1 = v1 * (-1);
if(absv1 < v2)
return v1;
else if(absv1 > v2)
return v2;
else
return v2;
}
public static void main(String[] args) {
int t[] = {6,5,8,8,-2,-5,0,-3,-5,9,7,4};
Solution.trier(t);
}
}
To maintain O(n) time complexity and getting the desired results we have to add another variable called 'num' and assign to it 'near' before changing it's value. And finally make necessary checks. The improvements in the code are are:
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2};
int curr = 0;
int near = data[0];
int num=near;
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) ) {
num=near;
near = data[i];
}
}
if(near<0 && near*(-1)==num)
near=num;
System.out.println( near );
}
}
We have to find the Closest number to zero.
The given array can have negative values also.
So the easiest approach would append the '0' in the given array and sort it and return the element next to '0'
append the 0
Sort the Array
Return the element next to 0.
`
N = int(input())
arr = list(map(int, input().split()))
arr.append(0)
arr.sort()
zeroIndex = arr.index(0)
print(arr[zeroIndex + 1])
--> If this solution leaves corner cases please let me know also.
`
if you don't wanna use the inbuilt library function use the below code (just an and condition with your existing code)-
public class CloseToZero {
public static void main(String[] args) {
int[] data = {2,3,-2,-1,1};
int curr = 0;
int near = data[0];
// find the element nearest to zero
for ( int i=0; i < data.length; i++ ){
curr = data[i] * data[i];
if ( curr <= (near * near) && !((curr - (near * near) == 0) && data[i] < 0)) {
near = data[i];
}
}
System.out.println( near );
}
}
!((curr - (near * near) == 0) && data[i] < 0) : skip asignment if if near and curr is just opposit in sign and the curr is negative
public static int find(int[] ints) {
if (ints==null) return 0;
int min= ints[0]; //a random value initialisation
for (int k=0;k<ints.length;k++) {
// if a positive value is matched it is prioritized
if (ints[k]==Math.abs(min) || Math.abs(ints[k])<Math.abs(min))
min=ints[k];
}
return min;
}
public int check() {
int target = 0;
int[] myArray = { 40, 20, 100, 30, -1, 70, -10, 500 };
int result = myArray[0];
for (int i = 0; i < myArray.length; i++) {
if (myArray[i] == target) {
result = myArray[i];
return result;
}
if (myArray[i] > 0 && result >= (myArray[i] - target)) {
result = myArray[i];
}
}
return result;
}
I have added a check for the positive number itself.
Please share your views folks!!
public class ClosesttoZero {
static int closZero(int[] ints) {
int result=ints[0];
for(int i=1;i<ints.length;i++) {
if(Math.abs(result)>=Math.abs(ints[i])) {
result=Math.abs(ints[i]);
}
}
return result;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] ints= {1,1,5,8,4,-9,0,6,7,1};
int result=ClosesttoZero.closZero(ints);
System.out.println(result);
}
}
It can be done simply by making all numbers positive using absolute value then sort the Array:
int[] arr = {9, 1, 4, 5, 6, 7, -1, -2};
for (int i = 0; i < arr.length; ++i)
{
arr[i] = Math.abs(arr[i]);
}
Arrays.sort(arr);
System.out.println("Closest value to 0 = " + arr[0]);
import java.math.*;
class Solution {
static double closestToZero(double[] ts) {
if (ts.length == 0)
return 0;
double closestToZero = ts[0];
double absClosest = Math.abs(closestToZero);
for (int i = 0; i < ts.length; i++) {
double absValue = Math.abs(ts[i]);
if (absValue < absClosest || absValue == absClosest && ts[i] > 0) {
closestToZero = ts[i];
absClosest = absValue;
}
}
return closestToZero;
}
}
//My solution priorizing positive numbers contraint
int closestToZero = Integer.MAX_VALUE;//or we
for(int i = 0 ; i < arrayInt.length; i++) {
if (Math.abs(arrayInt[i]) < closestToZero
|| Math.abs(closestToZero) == Math.abs(arrayInt[i]) && arrayInt[i] > 0 ) {
closestToZero = arrayInt[i];
}
}
I had an interview question which i could not solve.
Write method (not a program) in Java Programming Language that will move all even numbers on the first half and odd numbers to the second half in an integer array.
E.g. Input = {3,8,12,5,9,21,6,10}; Output = {12,8,6,10,3,5,9,21}.
The method should take integer array as parameter and move items in the same array (do not create another array). The numbers may be in different order than original array. This is algorithm test, so try to give as efficient algorithm as you can (possibly linear O(n) algorithm). Avoid using built in functions/API. *
Also some basic intro to what is data structure efficiency
Keep two indices: one to the first odd number and one to the last even number. Swap such numbers and update indices.
(With a lot of help from #manu-fatto's suggestion) I believe this would do it:
private static int[] OddSort(int[] items)
{
int oddPos, nextEvenPos;
for (nextEvenPos = 0;
nextEvenPos < items.Length && items[nextEvenPos] % 2 == 0;
nextEvenPos++) { }
// nextEvenPos is now positioned at the first odd number in the array,
// i.e. it is the next place an even number will be placed
// We already know that items[nextEvenPos] is odd (from the condition of the
// first loop), so we'll start looking for even numbers at nextEvenPos + 1
for (oddPos = nextEvenPos + 1; oddPos < items.Length; oddPos++)
{
// If we find an even number
if (items[oddPos] % 2 == 0)
{
// Swap the values
int temp = items[nextEvenPos];
items[nextEvenPos] = items[oddPos];
items[oddPos] = temp;
// And increment the location for the next even number
nextEvenPos++;
}
}
return items;
}
This algorithm traverses the list exactly 1 time (inspects each element exactly once), so the efficiency is O(n).
// to do this in one for loop
public static void evenodd(int[] integer) {
int i = 0, temp = 0;
int j = integer.length - 1;
while (j >= i) {
// swap if found odd even combo at i and j
if (integer[i] % 2 != 0 && integer[j] % 2 == 0) {
temp = integer[i];
integer[i] = integer[j];
integer[j] = temp;
i++;
j--;
} else {
if (integer[i] % 2 == 0) {
i++;
}
if (integer[j] % 2 == 1) {
j--;
}
}
}
}
#JLRishe,
Your algorithm doesn't maintain the order. For a simple example, say {1,5,2}, you will change the array to {2,5,1}. I could not comment below your post as I am a new user and lack reputations.
public static void sorted(int [] integer) {
int i, j , temp;
for (i = 0; i < integer.length; i++) {
if (integer[i] % 2 == 0) {
for (j = i; j < integer.length; j++) {
if (integer[j] % 2 == 1) {
temp = y[i];
y[i] = y[j];
y[j] = temp;
}
}
}
System.out.println(integer[i]);
}
public static void main(String args[]) {
sorted(new int[]{1, 2,7, 9, 4});
}
}
The answer is 1, 7, 9, 2, 4.
Could it be that you were asked to implement a very basic version of the BubbleSort where the sort value of element e, where e = arr[i], = e%2==1 ? 1 : -1 ?
Regards
Leon
class Demo
{
public void sortArray(int[] a)
{
int len=a.length;
int j=len-1;
for(int i=0;i<len/2+1;i++)
{
if(a[i]%2!=0)
{
while(a[j]%2!=0 && j>(len/2)-1)
j--;
if(j<=(len/2)-1)
break;
a[i]=a[i]+a[j];
a[j]=a[i]-a[j];
a[i]=a[i]-a[j];
}
}
for(int i=0;i<len;i++)
System.out.println(a[i]);
}
public static void main(String s[])
{
int a[]=new int[10];
System.out.println("Enter 10 numbers");
java.util.Scanner sc=new java.util.Scanner(System.in);
for(int i=0;i<10;i++)
{
a[i]=sc.nextInt();
}
new Demo().sortArray(a);
}
}
private static void rearrange(int[] a) {
int i,j,temp;
for(i = 0, j = a.length - 1; i < j ;i++,j--) {
while(a[i]%2 == 0 && i != a.length - 1) {
i++;
}
while(a[j]%2 == 1 && j != 0) {
j--;
}
if(i>j)
break;
else {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
public void sortEvenOddIntegerArray(int[] intArray){
boolean loopRequired = false;
do{
loopRequired = false;
for(int i = 0;i<intArray.length-1;i++){
if(intArray[i] % 2 != 0 && intArray[i+1] % 2 == 0){
int temp = intArray[i];
intArray[i] = intArray[i+1];
intArray[i+1] = temp;
loopRequired = true;
}
}
}while(loopRequired);
}
You can do this with a single loop by moving odd items to the end of the array when you find them.
static void EvensToLeft(int[] items) {
int end = items.length;
for (int i = 0; i < end; i++) {
if (items[i] % 2) {
int t = items[i];
items[i--] = items[--end];
items[end] = t;
}
}
}
Given an input array of length n the inner loop executes exactly n times, and computes the parity of each array element exactly once.
Use two counters i=0 and j=a.length-1 and keep swapping even and odd elements that are in the wrong place.
public int[] evenOddSort(int[] a) {
int i = 0;
int j = a.length - 1;
int temp;
while (i < j) {
if (a[i] % 2 == 0) {
i++;
} else if (a[j] % 2 != 0) {
j--;
} else {
temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
return a;
}
public class SeperatOddAndEvenInList {
public static int[] seperatOddAndEvnNos(int[] listOfNumbers) {
int oddNumPointer = 0;
int evenNumPointer = listOfNumbers.length - 1;
while(oddNumPointer <= evenNumPointer) {
if(listOfNumbers[oddNumPointer] % 2 == 0) { //even number, swap to front of last known even number
int temp;
temp = listOfNumbers[oddNumPointer];
listOfNumbers[oddNumPointer] = listOfNumbers[evenNumPointer];
listOfNumbers[evenNumPointer] = temp;
evenNumPointer--;
}
else { //odd number, go ahead... capture next element
oddNumPointer++;
}
}
return listOfNumbers;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int []arr = {3, 8, 12, 5, 9, 21, 6, 10};
int[] seperatedArray = seperatOddAndEvnNos(arr);
for (int i : seperatedArray) {
System.out.println(i);
}
}
}
public class ArraysSortEvensFirst {
public static void main(String[] args) {
int[] arr = generateTestData();
System.out.println(Arrays.toString(arr));
ArraysSortEvensFirst test = new ArraysSortEvensFirst();
test.sortEvensFirst(arr);
}
private static int[] generateTestData() {
int[] arr = {1,3,5,6,9,2,4,5,7};
return arr;
}
public int[] sortEvensFirst(int[] arr) {
int end = arr.length;
int last = arr.length-1;
for(int i=0; i < arr.length; i++) {
// find odd elements, then move to even slots
if(arr[i]%2 > 0) {
int k = findEven(last, arr);
if(k > i) swap(arr, i, k);
last = k;
}
}
System.out.println(Arrays.toString(arr));
return arr;
}
public int findEven(int last, int[] arr) {
for(int k = last; k > 0; k--) {
if(arr[k]%2 == 0) {
return k;
}
}
return -1; // not found;
}
public void swap(int[] arr, int x, int y) {
int temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
}
Output:
[1, 3, 5, 6, 9, 2, 4, 5, 7]
[4, 2, 6, 5, 9, 3, 1, 5, 7]
efficiency is O(log n).
public class TestProg {
public static void main(String[] args) {
int[] input = { 32, 54, 35, 18, 23, 17, 2 };
int front = 0;
int mid = input.length - 1;
for (int start = 0; start < input.length; start++) {
//if current element is odd
if (start < mid && input[start] % 2 == 1) {
//swapping element is also odd?
if (input[mid] % 2 == 1) {
mid--;
start--;
}
//swapping element is not odd then swap
else {
int tmp = input[mid];
input[mid] = input[start];
input[start] = tmp;
mid--;
}
}
}
for (int x : input)
System.out.print(x + " ");
}
}
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 4 years ago.
Improve this question
I just had a codility problem give me a hard time and I'm still trying to figure out how the space and time complexity constraints could have been met.
The problem is as follows:
A dominant member in the array is one that occupies over half the positions in the array, for example:
{3, 67, 23, 67, 67}
67 is a dominant member because it appears in the array in 3/5 (>50%) positions.
Now, you are expected to provide a method that takes in an array and returns an index of the dominant member if one exists and -1 if there is none.
Easy, right? Well, I could have solved the problem handily if it were not for the following constraints:
Expected time complexity is O(n)
Expected space complexity is O(1)
I can see how you could solve this for O(n) time with O(n) space complexities as well as O(n^2) time with O(1) space complexities, but not one that meets both O(n) time and O(1) space.
I would really appreciate seeing a solution to this problem. Don't worry, the deadline has passed a few hours ago (I only had 30 minutes), so I'm not trying to cheat. Thanks.
Googled "computing dominant member of array", it was the first result. See the algorithm described on page 3.
element x;
int count ← 0;
For(i = 0 to n − 1) {
if(count == 0) { x ← A[i]; count++; }
else if (A[i] == x) count++;
else count−−;
}
Check if x is dominant element by scanning array A
Basically observe that if you find two different elements in the array, you can remove them both without changing the dominant element on the remainder. This code just keeps tossing out pairs of different elements, keeping track of the number of times it has seen the single remaining unpaired element.
Find the median with BFPRT, aka median of medians (O(N) time, O(1) space). Then scan through the array -- if one number dominates, the median will be equal to that number. Walk through the array and count the number of instances of that number. If it's over half the array, it's the dominator. Otherwise, there is no dominator.
Adding a Java 100/100 O(N) time with O(1) space:
https://codility.com/demo/results/demoPNG8BT-KEH/
class Solution {
public int solution(int[] A) {
int indexOfCandidate = -1;
int stackCounter = 0, candidate=-1, value=-1, i =0;
for(int element: A ) {
if (stackCounter == 0) {
value = element;
++stackCounter;
indexOfCandidate = i;
} else {
if (value == element) {
++stackCounter;
} else {
--stackCounter;
}
}
++i;
}
if (stackCounter > 0 ) {
candidate = value;
} else {
return -1;
}
int countRepetitions = 0;
for (int element: A) {
if( element == candidate) {
++countRepetitions;
}
if(countRepetitions > (A.length / 2)) {
return indexOfCandidate;
}
}
return -1;
}
}
If you want to see the Java source code it's here, I added some test cases as comments as the beginning of the file.
Java solution with score 100%
public int solution(int[] array) {
int candidate=0;
int counter = 0;
// Find candidate for leader
for(int i=0; i<array.length; i++){
if(counter == 0) candidate = i;
if(array[i] == array[candidate]){
counter++;
}else {
counter--;
}
}
// Count candidate occurrences in array
counter = 0;
for(int i=0; i<array.length; i++){
if(array[i] == array[candidate]) counter++;
}
// Check that candidate occurs more than array.lenght/2
return counter>array.length/2 ? candidate : -1;
}
In python, we are lucky some smart people have bothered to implement efficient helpers using C and shipped it in the standard library. The collections.Counter is useful here.
>>> data = [3, 67, 23, 67, 67]
>>> from collections import Counter
>>> counter = Counter(data) # counter accepts any sequence/iterable
>>> counter # dict like object, where values are the occurrence
Counter({67: 3, 3: 1, 23: 1})
>>> common = counter.most_common()[0]
>>> common
(67, 3)
>>> common[0] if common[1] > len(data) / 2.0 + 1 else -1
67
>>>
If you prefer a function here is one ...
>>> def dominator(seq):
counter = Counter(seq)
common = counter.most_common()[0]
return common[0] if common[1] > len(seq) / 2.0 + 1 else -1
...
>>> dominator([1, 3, 6, 7, 6, 8, 6])
-1
>>> dominator([1, 3, 6, 7, 6, 8, 6, 6])
6
This question looks hard if a small trick does not come to the mind :). I found this trick in this document of codility : https://codility.com/media/train/6-Leader.pdf.
The linear solution is explained at the bottom of this document.
I implemented the following java program which gave me a score of 100 on the same lines.
public int solution(int[] A) {
Stack<Integer> stack = new Stack<Integer>();
for (int i =0; i < A.length; i++)
{
if (stack.empty())
stack.push(new Integer(A[i]));
else
{
int topElem = stack.peek().intValue();
if (topElem == A[i])
{
stack.push(new Integer(A[i]));
}
else
{
stack.pop();
}
}
}
if (stack.empty())
return -1;
int elem = stack.peek().intValue();
int count = 0;
int index = 0;
for (int i = 0; i < A.length; i++)
{
if (elem == A[i])
{
count++;
index = i;
}
}
if (count > ((double)A.length/2.0))
return index;
else
return -1;
}
Here's my C solution which scores 100%
int solution(int A[], int N) {
int candidate;
int count = 0;
int i;
// 1. Find most likely candidate for the leader
for(i = 0; i < N; i++){
// change candidate when count reaches 0
if(count == 0) candidate = i;
// count occurrences of candidate
if(A[i] == A[candidate]) count++;
else count--;
}
// 2. Verify that candidate occurs more than N/2 times
count = 0;
for(i = 0; i < N; i++) if(A[i] == A[candidate]) count++;
if (count <= N/2) return -1;
return candidate; // return index of leader
}
100%
import java.util.HashMap;
import java.util.Map;
class Solution {
public static int solution(int[] A) {
final int N = A.length;
Map<Integer, Integer> mapOfOccur = new HashMap((N/2)+1);
for(int i=0; i<N; i++){
Integer count = mapOfOccur.get(A[i]);
if(count == null){
count = 1;
mapOfOccur.put(A[i],count);
}else{
mapOfOccur.replace(A[i], count, ++count);
}
if(count > N/2)
return i;
}
return -1;
}
}
Does it have to be a particularly good algorithm? ;-)
static int dominant(final int... set) {
final int[] freqs = new int[Integer.MAX_VALUE];
for (int n : set) {
++freqs[n];
}
int dom_freq = Integer.MIN_VALUE;
int dom_idx = -1;
int dom_n = -1;
for (int i = set.length - 1; i >= 0; --i) {
final int n = set[i];
if (dom_n != n) {
final int freq = freqs[n];
if (freq > dom_freq) {
dom_freq = freq;
dom_n = n;
dom_idx = i;
} else if (freq == dom_freq) {
dom_idx = -1;
}
}
}
return dom_idx;
}
(this was primarily meant to poke fun at the requirements)
Consider this 100/100 solution in Ruby:
# Algorithm, as described in https://codility.com/media/train/6-Leader.pdf:
#
# * Iterate once to find a candidate for dominator.
# * Count number of candidate occurences for the final conclusion.
def solution(ar)
n_occu = 0
candidate = index = nil
ar.each_with_index do |elem, i|
if n_occu < 1
# Here comes a new dominator candidate.
candidate = elem
index = i
n_occu += 1
else
if candidate == elem
n_occu += 1
else
n_occu -= 1
end
end # if n_occu < 1
end
# Method result. -1 if no dominator.
# Count number of occurences to check if candidate is really a dominator.
if n_occu > 0 and ar.count {|_| _ == candidate} > ar.size/2
index
else
-1
end
end
#--------------------------------------- Tests
def test
sets = []
sets << ["4666688", [1, 2, 3, 4], [4, 6, 6, 6, 6, 8, 8]]
sets << ["333311", [0, 1, 2, 3], [3, 3, 3, 3, 1, 1]]
sets << ["313131", [-1], [3, 1, 3, 1, 3, 1]]
sets << ["113333", [2, 3, 4, 5], [1, 1, 3, 3, 3, 3]]
sets.each do |name, one_of_expected, ar|
out = solution(ar)
raise "FAILURE at test #{name.inspect}: #{out.inspect} not in #{expected.inspect}" if not one_of_expected.include? out
end
puts "SUCCESS: All tests passed"
end
Here is an easy to read, 100% score version in Objective-c
if (A.count > 100000)
return -1;
NSInteger occur = 0;
NSNumber *candidate = nil;
for (NSNumber *element in A){
if (!candidate){
candidate = element;
occur = 1;
continue;
}
if ([candidate isEqualToNumber:element]){
occur++;
}else{
if (occur == 1){
candidate = element;
continue;
}else{
occur--;
}
}
}
if (candidate){
occur = 0;
for (NSNumber *element in A){
if ([candidate isEqualToNumber:element])
occur++;
}
if (occur > A.count / 2)
return [A indexOfObject:candidate];
}
return -1;
100% score JavaScript solution. Technically it's O(nlogn) but still passed.
function solution(A) {
if (A.length == 0)
return -1;
var S = A.slice(0).sort(function(a, b) {
return a - b;
});
var domThresh = A.length/2;
var c = S[Math.floor(domThresh)];
var domCount = 0;
for (var i = 0; i < A.length; i++) {
if (A[i] == c)
domCount++;
if (domCount > domThresh)
return i;
}
return -1;
}
This is the solution in VB.NET with 100% performance.
Dim result As Integer = 0
Dim i, ladderVal, LadderCount, size, valCount As Integer
ladderVal = 0
LadderCount = 0
size = A.Length
If size > 0 Then
For i = 1 To size - 1
If LadderCount = 0 Then
LadderCount += 1
ladderVal = A(i)
Else
If A(i) = ladderVal Then
LadderCount += 1
Else
LadderCount -= 1
End If
End If
Next
valCount = 0
For i = 0 To size - 1
If A(i) = ladderVal Then
valCount += 1
End If
Next
If valCount <= size / 2 Then
result = 0
Else
LadderCount = 0
For i = 0 To size - 1
If A(i) = ladderVal Then
valCount -= 1
LadderCount += 1
End If
If LadderCount > (LadderCount + 1) / 2 And (valCount > (size - (i + 1)) / 2) Then
result += 1
End If
Next
End If
End If
Return result
See the correctness and performance of the code
Below solution resolves in complexity O(N).
public int solution(int A[]){
int dominatorValue=-1;
if(A != null && A.length>0){
Hashtable<Integer, Integer> count=new Hashtable<>();
dominatorValue=A[0];
int big=0;
for (int i = 0; i < A.length; i++) {
int value=0;
try{
value=count.get(A[i]);
value++;
}catch(Exception e){
}
count.put(A[i], value);
if(value>big){
big=value;
dominatorValue=A[i];
}
}
}
return dominatorValue;
}
100% in PHP https://codility.com/demo/results/trainingVRQGQ9-NJP/
function solution($A){
if (empty($A)) return -1;
$copy = array_count_values($A); // 3 => 7, value => number of repetition
$max_repetition = max($copy); // at least 1 because the array is not empty
$dominator = array_search($max_repetition, $copy);
if ($max_repetition > count($A) / 2) return array_search($dominator, $A); else return -1;
}
i test my code its work fine in arrays lengths between 2 to 9
public static int sol (int []a)
{
int count = 0 ;
int candidateIndex = -1;
for (int i = 0; i <a.length ; i++)
{
int nextIndex = 0;
int nextOfNextIndex = 0;
if(i<a.length-2)
{
nextIndex = i+1;
nextOfNextIndex = i+2;
}
if(count==0)
{
candidateIndex = i;
}
if(a[candidateIndex]== a[nextIndex])
{
count++;
}
if (a[candidateIndex]==a[nextOfNextIndex])
{
count++;
}
}
count -- ;
return count>a.length/2?candidateIndex:-1;
}
Adding a Java 100/100 O(N) time with O(1) space:
// you can also use imports, for example:
import java.util.Stack;
// you can write to stdout for debugging purposes, e.g.
// System.out.println("this is a debug message");
class Solution {
public int solution(int[] A) {
// write your code in Java SE 8
int count = 0;
Stack<Integer> integerStack = new Stack<Integer>();
for (int i = 0; i < A.length; i++) {
if (integerStack.isEmpty()) {
integerStack.push(A[i]);
} else if (integerStack.size() > 0) {
if (integerStack.peek() == A[i])
integerStack.push(A[i]);
else
integerStack.pop();
}
}
if (!integerStack.isEmpty()) {
for (int i = 0; i < integerStack.size(); i++) {
for (int j = 0; j < A.length; j++) {
if (integerStack.get(i) == A[j])
count++;
if (count > A.length / 2)
return j;
}
count = 0;
}
}
return -1;
}
}
Here is test result from codility.
I think this question has already been resolved somewhere. The "official" solution should be :
public int dominator(int[] A) {
int N = A.length;
for(int i = 0; i< N/2+1; i++)
{
int count=1;
for(int j = i+1; j < N; j++)
{
if (A[i]==A[j]) {count++; if (count > (N/2)) return i;}
}
}
return -1;
}
How about sorting the array first? You then compare middle and first and last elements of the sorted array to find the dominant element.
public Integer findDominator(int[] arr) {
int[] arrCopy = arr.clone();
Arrays.sort(arrCopy);
int length = arrCopy.length;
int middleIndx = (length - 1) /2;
int middleIdxRight;
int middleIdxLeft = middleIndx;
if (length % 2 == 0) {
middleIdxRight = middleIndx+1;
} else {
middleIdxRight = middleIndx;
}
if (arrCopy[0] == arrCopy[middleIdxRight]) {
return arrCopy[0];
}
if (arrCopy[middleIdxLeft] == arrCopy[length -1]) {
return arrCopy[middleIdxLeft];
}
return null;
}
C#
int dominant = 0;
int repeat = 0;
int? repeatedNr = null;
int maxLenght = A.Length;
int halfLenght = A.Length / 2;
int[] repeations = new int[A.Length];
for (int i = 0; i < A.Length; i++)
{
repeatedNr = A[i];
for (int j = 0; j < A.Length; j++)
{
if (repeatedNr == A[j])
{
repeations[i]++;
}
}
}
repeatedNr = null;
for (int i = 0; i < repeations.Length; i++)
{
if (repeations[i] > repeat)
{
repeat = repeations[i];
repeatedNr = A[i];
}
}
if (repeat > halfLenght)
dominant = int.Parse(repeatedNr.ToString());
class Program
{
static void Main(string[] args)
{
int []A= new int[] {3,6,2,6};
int[] B = new int[A.Length];
Program obj = new Program();
obj.ABC(A,B);
}
public int ABC(int []A, int []B)
{
int i,j;
int n= A.Length;
for (j=0; j<n ;j++)
{
int count = 1;
for (i = 0; i < n; i++)
{
if ((A[j]== A[i] && i!=j))
{
count++;
}
}
int finalCount = count;
B[j] = finalCount;// to store the no of times a number is repeated
}
// int finalCount = count / 2;
int finalCount1 = B.Max();// see which number occurred max times
if (finalCount1 > (n / 2))
{ Console.WriteLine(finalCount1); Console.ReadLine(); }
else
{ Console.WriteLine("no number found"); Console.ReadLine(); }
return -1;
}
}
In Ruby you can do something like
def dominant(a)
hash = {}
0.upto(a.length) do |index|
element = a[index]
hash[element] = (hash[element] ? hash[element] + 1 : 1)
end
res = hash.find{|k,v| v > a.length / 2}.first rescue nil
res ||= -1
return res
end
#Keith Randall solution is not working for {1,1,2,2,3,2,2}
his solution was:
element x;
int count ← 0;
For(i = 0 to n − 1) {
if(count == 0) { x ← A[i]; count++; }
else if (A[i] == x) count++;
else count−−;
}
Check if x is dominant element by scanning array A
I converted it into java as below:
int x = 0;
int count = 0;
for(int i = 0; i < (arr.length - 1); i++) {
if(count == 0) {
x = arr[i];
count++;
}
else if (arr[i] == x)
count++;
else count--;
}
return x;
Out put : 3
Expected: 2
This is my answer in Java: I store a count in seperate array which counts duplicates of each of the entries of the input array and then keeps a pointer to the array position that has the most duplicates. This is the dominator.
private static void dom(int[] a) {
int position = 0;
int max = 0;
int score = 0;
int counter = 0;
int[]result = new int[a.length];
for(int i = 0; i < a.length; i++){
score = 0;
for(int c = 0; c < a.length;c++){
if(a[i] == a[c] && c != i ){
score = score + 1;
result[i] = score;
if(result[i] > position){
position = i;
}
}
}
}
//This is just to facilitate the print function and MAX = the number of times that dominator number was found in the list.
for(int x = 0 ; x < result.length-1; x++){
if(result[x] > max){
max = result[x] + 1;
}
}
System.out.println(" The following number is the dominator " + a[position] + " it appears a total of " + max);
}