Java Interface Testing and Coding Issues - java
I have been working on this assignment for the past few hours and I'm stuck on the last method Histogram required for the assignment, I have problems with testing and the code probably (I'm using NetBeans).
the method should do this >
histogram: Takes a positive number n indicating the number of divisions in which
the span of the data is divided, and returns an array of integers of length n, where
each element of the array contains the count of the elements that fall into this
division. For example, if the data is (0.5, 1.2, 2.4, 9.8, 5.1, 10.5), then its span is
10.0 (from 0.5 to 10.5). histogram(4) would divide this range into four segments:
0.5—3.0, 3.0—5.5, 5.5—8.0, and 8.0—10.5. Inspecting the data, we see that 3 values
fall in the first segment, 1 value in the second, 0 values in the third, and 2 values
in the fourth. Therefore, the returned value is an array of length 4 containing the
values (3, 1, 0, 2) in that order.
Note that the sum of the elements in the returned array is equal to the number of
elements in the data array.
here is the code:
#Override
public int[] histogram(int divisions) {
int[] wide = new int[divisions];
double segment = span() / divisions;
for (int i = 0; i < data.length; i++) {
if (data[i] <= (smallestElement() + segment)) {
wide[0] = wide[0]+ 1;
} else if (data[i] <= (smallestElement() + (2 * segment))) {
wide[1] = wide[1]+ 1;
} else if (data[i] <= (smallestElement() + (3 * segment))) {
wide[2] = wide[2]+ 1;
} else if (data[i] <= (smallestElement() + (4 * segment))) {
wide[3] = wide[3]+ 1;
}
}
return wide;
}
and here is the test of the method above:
#Test
public void testHistogram() {
double[] data = new double[3];
data = new double[]{0.5, 1.2, 2.4, 9.8, 5.1, 10.5};
int[] data2 = new int[4];
data2 = new int[]{3, 1, 0, 2};
DoubleArrayStatisticalOutcomes a = new DoubleArrayStatisticalOutcomes(data);
assertArrayEquals(data2, a.histogram(4));
}
I use WebCat to submit my work, and when I submit the assignment it tells me that there's some tests missing for the method plus this "histogram is not accounting for the correct number of elements", my question is does the issue occur in the coding itself or am i missing something, same with the test.
Thanks in advance.
You’re only testing your method with the values from the example. The problem is that you probably wrote the method with this particular example in mind. What will happen if you try to make a histogram with a different length?
You should write more tests with different data and different parameters, and check that they all pass.
Related
How to add two integers represented by two arrays efficiently, putting the solution into another array
Time ago, I was asked during an interview to sum two Integers represented by arrays, putting the solution into another array. Part of the interview idea was for me to provide an efficient solution. Since then, I have been searching for a simple and efficient solution to this problem, and I didn't find none yet. So I would like to share my solution with the community and ask if any of you can help to improve efficiency. This example looks like O(mn) where mn is the size of the biggest array between m or n and, where m and n represents the size of each integer array to sum. Thus, it looks as though it is working in linear time. public class ArrayRudiments { /** * Add two integers represented by two arrays * * NOTE: Integer as a natural number, not as a programming language data type. * Thus, the integer can be as big as the array permits. * * #param m first number as array * #param n second number as array * #return integer sum solution as array */ public Integer[] sum(Integer m[], Integer n[]) { int carry = 0, csum = 0; final Vector<Integer> solution = new Vector<Integer>(); for (int msize = m.length - 1, nsize = n.length - 1; msize >= 0 || nsize >= 0; msize--, nsize--) { csum = (msize < 0 ? 0 : m[msize]) + (nsize < 0 ? 0 : n[nsize]) + carry; carry = csum / 10; solution.insertElementAt(csum % 10, 0); } if (carry > 0) { solution.insertElementAt(carry, 0); } return solution.toArray(new Integer[] {}); } } The problem or trick here is that the not linear time job is carried out by the Vector class inserting new elements and resizing the solution array. This way, the solution is not working in linear time. Is it possible to create a similar solution without Vector class? You can also see a working tested version of this code in https://github.com/lalounam/rudiments
As SSP has said in the comments, you should create an ArrayList with an initial capacity, of Math.max(m.length, n.length) + 1. That is the maximum number of digits of the sum. int arrayCapacity = Math.max(m.length, n.length) + 1; final List<Integer> solution = new ArrayList<>(arrayCapacity); Then you need to fill this with 0s: for (int i = 0 ; i < arrayCapacity ; i++) { solution.add(0); } Here's the "trick". In the main for loop, you don't fill the array from the start, you fill it from the end. Instead of insertElementAt the start, you set the element at whatever index we are iterating at, plus 1, because solution is one longer than the longer of m and n. solution.set(Math.max(msize, nsize) + 1, csum % 10); This is essentially filling the list "from the back". And at the end you resize the list like this: if (carry > 0) { solution.set(0, carry); return solution.toArray(new Integer[] {}); } else { return solution.subList(1, solution.size()).toArray(new Integer[] {}); }
How can I find out the four unique random numbers in Android within the range of 1 to 60?
This is what I tried so far in my app. I got this code by searching it from Google. Inside the Button OnClick() I called the Arandom() method: public void Arandom(View view) { final int SET_SIZE_REQUIRED = 4; final int NUMBER_RANGE = 70; Random random = new Random(); Set set = new HashSet<Integer>(SET_SIZE_REQUIRED); while(set.size()< SET_SIZE_REQUIRED) { while (set.add(random.nextInt(NUMBER_RANGE)) != true) ; } assert set.size() == SET_SIZE_REQUIRED; ArrayList<Integer> Elements = new ArrayList<>(set); Log.i("Elements","A:" + Elements.get(0)); Log.i("Elements","B:" + Elements.get(1)); Log.i("Elements","C:" + Elements.get(2)); Log.i("Elements","D:" + Elements.get(3)); } Now I am able to get four unique random numbers by this code but the problem is there sum is greater then 60. Let me explain it little bit. When I run the code I get: A:61 B:45 C:31 D:49 This is the screen shot of my log cat So I want the sum of all the numbers should be in the specified range (which is 1 to 60). e.g: A = 20 , B = 25 , C = 3 and D = 11 then their sum is 59 which is within the range Now another e.g: Suppose A = 5 , B = 22 , C = 18 and D = 3 then their sum will be 48 When we Add A,B,C,D then their sum should not exceed the range that is 60 I am new to Android and Java, and I am learning on my own by searching some materials on Google.
Let's say your target sum is T. It's easiest if you try to pick the numbers in descending order (you can shuffle them afterwards, if you want). The largest number you can pick for the 1st of four numbers is T-6, because you need to pick 3, 2 and 1 for the smaller numbers. The smallest number you can pick is the one where n+(n-1)+2+1 = T, so T/2+1. So, pick the first number in the range (T/2+1) to T-6. Then repeat the process to pick the third-largest and second-largest, applying similar logic to determine the possible range. There should be no choice in the smallest number, it's just whatever else you need to add to make the final sum. Note that you need to take care with rounding of things like the T/2.
I made the return type an int[]. You know how big you want to make the set, so there is no need to use sets or lists. The input parameter is changed to SET_SIZE_REQUIRED instead of using view. Make sure that a funtion only has one purpose and not do a calculation and change on a view at the same time. Replace the 60f to something else if you want the sum to be more or less than 60. public int[] Arandom(int numberOfValues) { int[] values = new int[numberOfValues]; int sum = 0; for(int i = 0; i < numberOfValues; i++){ values[i] = (int)(Math.random() * 100); sum += values[i]; } float multiplier = 60f / sum; for(int i = 0; i < numberOfValues; i++){ values[i] = (int)(values[i] * multiplier); Log.i("Value " + (i + 1), values[i]); } return values; } Or just do this: public int[] Arandom(int numberOfValues) { int[] values = new int[numberOfValues]; for(int i = 0; i < numberOfValues; i++){ values[i] = (int)(Math.random() * (60f / numberOfValues)); Log.i("Value " + (i + 1), values[i]); } return values; }
How to calculate the percentage of even numbers in an array?
i am beginner and here is the method I am struggling with. Write a method called percentEven that accepts an array of integers as a parameter and returns the percentage of even numbers in the array as a real number. For example, if the array stores the elements {6, 2, 9, 11, 3}, then your method should return 40.0. If the array contains no even elements or no elements at all, return 0.0. here is what I have so far... public static double percentEven(int[]a){ int count = 0; double percent = 0.0; if (a.length > 0){ for ( int i = 0; i < a.length; i++){ if ( a[i] % 2 == 0){ count++; } } percent =(count/a.length)*100.0; } return percent; } i keep returning 0.0 when array contains a mix of even and odd elements but works fine for all even element array or all odd array? i can't see where the problem is? thanks in advance.
count/a.length returns 0 since you are dividing two ints, and the second operand is larger than the first. Change it to (double)count/a.length in order to perform floating point division. Alternately, change the order of operations to : percent = 100.0*count/a.length;
For a simple division like 2*100.0/5 = 40.0, the above logic would work fine but think about the situation where we have 51*100.0/83 the output would be less readable and its always advisable to truncate the percentage to a limited decimal digits. An example: int count = 51; Double percent = 0.0; int length = 83; percent = count*100.0/length; System.out.println(percent); output: 61.44578313253012 When you truncate it: Double truncatedDouble = new BigDecimal(percent ).setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue(); System.out.println(truncatedDouble); output: 61.446
#Bathsheba : Well said, thanks for the suggestion. Here is sample code : public class PercentEven { public static void main(String args[]){ int count = 0; int[] a={2, 5, 9, 11, 0}; // this can be dynamic.I tried diff values double percent = 0.0; if (a.length > 0){ for ( int i = 0; i < a.length; i++){ if ( a[i] % 2 == 0){ count++; } } percent = (100*count/a.length); } System.out.println(percent); } }
List<Integer> numbers = Arrays.asList(a); int number = numbers.stream().filter(n->n%2==0).count(); int percent = number*100.0/numbers.size(); I have done this in java 8
Junit Testing error [closed]
Closed. This question needs debugging details. It is not currently accepting answers. Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question. Closed 8 years ago. Improve this question I have an assignment on arrays I'm working on and one of the questions is to write a code for a histogram. The method histogram takes a positive number n indicating the number of divisions in which the span of the data is divided, and returns an array of integers of length n, where each element of the array contains the count of the elements that fall into this division. For example, if the data is (0:5; 1:2; 2:4; 9:8; 5:1; 10:5), then its span is 10:0 (from 0:5 to 10:5). histogram(4) would divide this range into four segments: 0.5—3.0, 3.0—5.5, 5.5—8.0, and 8.0—10.5. Inspecting the data, we see that 3 values fall in the first segment, 1 value in the second, 0 values in the third, and 2 values in the fourth. Therefore, the returned value is an array of length 4 containing the values (3; 1; 0; 2) in that order. Note that the sum of the elements in the returned array is equal to the number of elements in the data array. here is my code: #Override public int[] histogram(int divisions) { int[] range = new int[divisions]; double segment = span() / divisions; for (int i = 0; i < data.length; i++) { if (data[i] <= (smallestElement() + segment)) { range[0] += 1; } if (data[i] <= (smallestElement() + (2 * segment))) { range[1] += 1; } if (data[i] <= (smallestElement() + (3 * segment))) { range[2] += 1; } if (data[i] <= (smallestElement() + (4 * segment))) { range[3] += 1; } } return range; } and here is my Junit test for my method: #Test public void testHistogram() { double[] data = new double[3]; data = new double[]{0.5, 1.2, 2.4, 9.8, 5.1, 10.5}; int[] dat = new int[4]; dat = new int[]{3, 1, 0, 2}; DoubleArrayStatisticalOutcomes x = new DoubleArrayStatisticalOutcomes(data); assertArrayEquals(dat, x.histogram(4)); } the test is not passing. can someone tell me what I did wrong ?
You are incrementing all the histogram bins for each value. In your for loop, if a value is less than smallestValue() + segment, all the conditional statements are executed, not just the smallest it matches. This makes your histogram cumulative. There are four elements total in the first two bins. Add a continue statement in each if or make if 2-4 into else ifs. Your function also breaks down the moment you pass a value not equal to 4 as the tests are hardcoded. Try something like (untested): double lowerBound = smallestElement(); for (int i = 0; i < data.length; i++) { for (int j = 0; j < divisions; j++) { if (data[i] <= (lowerBound + (j+1) * segment)) { range[j] += 1; continue; } } }
Find duplicate element in array in time O(n)
I have been asked this question in a job interview and I have been wondering about the right answer. You have an array of numbers from 0 to n-1, one of the numbers is removed, and replaced with a number already in the array which makes a duplicate of that number. How can we detect this duplicate in time O(n)? For example, an array of 4,1,2,3 would become 4,1,2,2. The easy solution of time O(n2) is to use a nested loop to look for the duplicate of each element.
This can be done in O(n) time and O(1) space. (The algorithm only works because the numbers are consecutive integers in a known range): In a single pass through the vector, compute the sum of all the numbers, and the sum of the squares of all the numbers. Subtract the sum of all the numbers from N(N-1)/2. Call this A. Subtract the sum of the squares from N(N-1)(2N-1)/6. Divide this by A. Call the result B. The number which was removed is (B + A)/2 and the number it was replaced with is (B - A)/2. Example: The vector is [0, 1, 1, 2, 3, 5]: N = 6 Sum of the vector is 0 + 1 + 1 + 2 + 3 + 5 = 12. N(N-1)/2 is 15. A = 3. Sum of the squares is 0 + 1 + 1 + 4 + 9 + 25 = 40. N(N-1)(2N-1)/6 is 55. B = (55 - 40)/A = 5. The number which was removed is (5 + 3) / 2 = 4. The number it was replaced by is (5 - 3) / 2 = 1. Why it works: The sum of the original vector [0, ..., N-1] is N(N-1)/2. Suppose the value a was removed and replaced by b. Now the sum of the modified vector will be N(N-1)/2 + b - a. If we subtract the sum of the modified vector from N(N-1)/2 we get a - b. So A = a - b. Similarly, the sum of the squares of the original vector is N(N-1)(2N-1)/6. The sum of the squares of the modified vector is N(N-1)(2N-1)/6 + b2 - a2. Subtracting the sum of the squares of the modified vector from the original sum gives a2 - b2, which is the same as (a+b)(a-b). So if we divide it by a - b (i.e., A), we get B = a + b. Now B + A = a + b + a - b = 2a and B - A = a + b - (a - b) = 2b.
We have the original array int A[N]; Create a second array bool B[N] too, of type bool=false. Iterate the first array and set B[A[i]]=true if was false, else bing!
You can do it in O(N) time without any extra space. Here is how the algorithm works : Iterate through array in the following manner : For each element encountered, set its corresponding index value to negative. Eg : if you find a[0] = 2. Got to a[2] and negate the value. By doing this you flag it to be encountered. Since you know you cannot have negative numbers, you also know that you are the one who negated it. Check if index corresponding to the value is already flagged negative, if yes you get the duplicated element. Eg : if a[0]=2 , go to a[2] and check if it is negative. Lets say you have following array : int a[] = {2,1,2,3,4}; After first element your array will be : int a[] = {2,1,-2,3,4}; After second element your array will be : int a[] = {2,-1,-2,3,4}; When you reach third element you go to a[2] and see its already negative. You get the duplicate.
Scan the array 3 times: XOR together all the array elements -> A. XOR together all the numbers from 0 to N-1 -> B. Now A XOR B = X XOR D, where X is the removed element, and D is the duplicate element. Choose any non-zero bit in A XOR B. XOR together all the array elements where this bit is set -> A1. XOR together all the numbers from 0 to N-1 where this bit is set -> B1. Now either A1 XOR B1 = X or A1 XOR B1 = D. Scan the array once more and try to find A1 XOR B1. If it is found, this is the duplicate element. If not, the duplicate element is A XOR B XOR A1 XOR B1.
Use a HashSet to hold all numbers already seen. It operates in (amortized) O(1) time, so the total is O(N).
I suggest using a BitSet. We know N is small enough for array indexing, so the BitSet will be of reasonable size. For each element of the array, check the bit corresponding to its value. If it is already set, that is the duplicate. If not, set the bit.
#rici is right about the time and space usage: "This can be done in O(n) time and O(1) space." However, the question can be expanded to broader requirement: it's not necessary that there is only one duplicate number, and numbers might not be consecutive. OJ puts it this way here: (note 3 apparently can be narrowed) Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. Note: You must not modify the array (assume the array is read only). You must use only constant, O(1) extra space. Your runtime complexity should be less than O(n2). There is only one duplicate number in the array, but it could be repeated more than once. The question is very well explained and answered here by Keith Schwarz, using Floyd's cycle-finding algorithm: The main trick we need to use to solve this problem is to notice that because we have an array of n elements ranging from 0 to n - 2, we can think of the array as defining a function f from the set {0, 1, ..., n - 1} onto itself. This function is defined by f(i) = A[i]. Given this setup, a duplicated value corresponds to a pair of indices i != j such that f(i) = f(j). Our challenge, therefore, is to find this pair (i, j). Once we have it, we can easily find the duplicated value by just picking f(i) = A[i]. But how are we to find this repeated value? It turns out that this is a well-studied problem in computer science called cycle detection. The general form of the problem is as follows. We are given a function f. Define the sequence x_i as x_0 = k (for some k) x_1 = f(x_0) x_2 = f(f(x_0)) ... x_{n+1} = f(x_n) Assuming that f maps from a domain into itself, this function will have one of three forms. First, if the domain is infinite, then the sequence could be infinitely long and nonrepeating. For example, the function f(n) = n + 1 on the integers has this property - no number is ever duplicated. Second, the sequence could be a closed loop, which means that there is some i so that x_0 = x_i. In this case, the sequence cycles through some fixed set of values indefinitely. Finally, the sequence could be "rho-shaped." In this case, the sequence looks something like this: x_0 -> x_1 -> ... x_k -> x_{k+1} ... -> x_{k+j} ^ | | | +-----------------------+ That is, the sequence begins with a chain of elements that enters a cycle, then cycles around indefinitely. We'll denote the first element of the cycle that is reached in the sequence the "entry" of the cycle. An python implementation can also be found here: def findDuplicate(self, nums): # The "tortoise and hare" step. We start at the end of the array and try # to find an intersection point in the cycle. slow = 0 fast = 0 # Keep advancing 'slow' by one step and 'fast' by two steps until they # meet inside the loop. while True: slow = nums[slow] fast = nums[nums[fast]] if slow == fast: break # Start up another pointer from the end of the array and march it forward # until it hits the pointer inside the array. finder = 0 while True: slow = nums[slow] finder = nums[finder] # If the two hit, the intersection index is the duplicate element. if slow == finder: return slow
Use hashtable. Including an element in a hashtable is O(1).
One working solution: asume number are integers create an array of [0 .. N] int[] counter = new int[N]; Then iterate read and increment the counter: if (counter[val] >0) { // duplicate } else { counter[val]++; }
This can be done in O(n) time and O(1) space. Without modifying the input array The idea is similar to finding the starting node of a loop in a linked list. Maintain two pointers: fast and slow slow = a[0] fast = a[a[0]] loop till slow != fast Once we find the loop (slow == fast) Reset slow back to zero slow = 0 find the starting node while(slow != fast){ slow = a[slow]; fast = a[fast]; } slow is your duplicate number. Here's a Java implementation: class Solution { public int findDuplicate(int[] nums) { if(nums.length <= 1) return -1; int slow = nums[0], fast = nums[nums[0]]; //slow = head.next, fast = head.next.next while(slow != fast){ //check for loop slow = nums[slow]; fast = nums[nums[fast]]; } if(slow != fast) return -1; slow = 0; //reset one pointer while(slow != fast){ //find starting point of loop slow = nums[slow]; fast = nums[fast]; } return slow; } }
This is an alternative solution in O(n) time and O(1) space. It is similar to rici's. I find it a bit easier to understand but, in practice, it will overflow faster. Let X be the missing number and R be the repeated number. We can assume the numbers are from [1..n], i.e. zero does not appear. In fact, while looping through the array, we can test if zero was found and return immediately if not. Now consider: sum(A) = n (n + 1) / 2 - X + R product(A) = n! R / X where product(A) is the product of all element in A skipping the zero. We have two equations in two unknowns from which X and R can be derived algebraically. Edit: by popular demand, here is a worked-out example: Let's set: S = sum(A) - n (n + 1) / 2 P = n! / product(A) Then our equations become: R - X = S X = R P which can be solved to: R = S / (1 - P) X = P R = P S / (1 - P) Example: A = [0 1 2 2 4] n = A.length - 1 = 4 S = (1 + 2 + 2 + 4) - 4 * 5 / 2 = -1 P = 4! / (1 * 2 * 2 * 4) = 3 / 2 R = -1 / (1 - 3/2) = -1 / -1/2 = 2 X = 3/2 * 2 = 3
You could proceed as follows: sort your array by using a Linear-time sorting algorithm (e.g. Counting sort) - O(N) scan the sorted array and stop as soon as two consecutive elements are equal - O(N)
public class FindDuplicate { public static void main(String[] args) { // assume the array is sorted, otherwise first we have to sort it. // time efficiency is o(n) int elementData[] = new int[] { 1, 2, 3, 3, 4, 5, 6, 8, 8 }; int count = 1; int element1; int element2; for (int i = 0; i < elementData.length - 1; i++) { element1 = elementData[i]; element2 = elementData[count]; count++; if (element1 == element2) { System.out.println(element2); } } } }
public void duplicateNumberInArray { int a[] = new int[10]; Scanner inp = new Scanner(System.in); for(int i=1;i<=5;i++){ System.out.println("enter no. "); a[i] = inp.nextInt(); } Set<Integer> st = new HashSet<Integer>(); Set<Integer> s = new HashSet<Integer>(); for(int i=1;i<=5;i++){ if(!st.add(a[i])){ s.add(a[i]); } } Iterator<Integer> itr = s.iterator(); System.out.println("Duplicate numbers are"); while(itr.hasNext()){ System.out.println(itr.next()); } } First of all creating an array of integer using Scanner class. Then iterating a loop through the numbers and checking if the number can be added to set (Numbers can be added to set only when that particular number should not be in set already, means set does not allow duplicate no. to add and return a boolean vale FALSE on adding duplicate value).If no. cannot be added means it is duplicate so add that duplicate number into another set, so that we can print later. Please note onething that we are adding the duplicate number into a set because it might be possible that duplicate number might be repeated several times, hence add it only once.At last we are printing set using Iterator.
//This is similar to the HashSet approach but uses only one data structure: int[] a = { 1, 4, 6, 7, 4, 6, 5, 22, 33, 44, 11, 5 }; LinkedHashMap<Integer, Integer> map = new LinkedHashMap<Integer, Integer>(); for (int i : a) { map.put(i, map.containsKey(i) ? (map.get(i)) + 1 : 1); } Set<Entry<Integer, Integer>> es = map.entrySet(); Iterator<Entry<Integer, Integer>> it = es.iterator(); while (it.hasNext()) { Entry<Integer, Integer> e = it.next(); if (e.getValue() > 1) { System.out.println("Dupe " + e.getKey()); } }
We can do using hashMap efficiently: Integer[] a = {1,2,3,4,0,1,5,2,1,1,1,}; HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); for(int x : a) { if (map.containsKey(x)) map.put(x,map.get(x)+1); else map.put(x,1); } Integer [] keys = map.keySet().toArray(new Integer[map.size()]); for(int x : keys) { if(map.get(x)!=1) { System.out.println(x+" repeats : "+map.get(x)); } }
This program is based on c# and if you want to do this program using another programming language you have to firstly change an array in accending order and compare the first element to the second element.If it is equal then repeated number found.Program is int[] array=new int[]{1,2,3,4,5,6,7,8,9,4}; Array.Sort(array); for(int a=0;a<array.Length-1;a++) { if(array[a]==array[a+1] { Console.WriteLine("This {0} element is repeated",array[a]); } } Console.WriteLine("Not repeated number in array");
sort the array O(n ln n) using the sliding window trick to traverse the array O(n) Space is O(1) Arrays.sort(input); for(int i = 0, j = 1; j < input.length ; j++, i++){ if( input[i] == input[j]){ System.out.println(input[i]); while(j < input.length && input[i] == input[j]) j++; i = j - 1; } } Test case int[] { 1, 2, 3, 7, 7, 8, 3, 5, 7, 1, 2, 7 } output 1, 2, 3, 7
Traverse through the array and check the sign of array[abs(array[i])], if positive make it as negative and if it is negative then print it, as follows: import static java.lang.Math.abs; public class FindRepeatedNumber { private static void findRepeatedNumber(int arr[]) { int i; for (i = 0; i < arr.length; i++) { if (arr[abs(arr[i])] > 0) arr[abs(arr[i])] = -arr[abs(arr[i])]; else { System.out.print(abs(arr[i]) + ","); } } } public static void main(String[] args) { int arr[] = { 4, 2, 4, 5, 2, 3, 1 }; findRepeatedNumber(arr); } } Reference: http://www.geeksforgeeks.org/find-duplicates-in-on-time-and-constant-extra-space/
As described, You have an array of numbers from 0 to n-1, one of the numbers is removed, and replaced with a number already in the array which makes a duplicate of that number. I'm assuming elements in the array are sorted except the duplicate entry. If this is the scenario , we can achieve the goal easily as below : public static void main(String[] args) { //int arr[] = { 0, 1, 2, 2, 3 }; int arr[] = { 1, 2, 3, 4, 3, 6 }; int len = arr.length; int iMax = arr[0]; for (int i = 1; i < len; i++) { iMax = Math.max(iMax, arr[i]); if (arr[i] < iMax) { System.out.println(arr[i]); break; }else if(arr[i+1] <= iMax) { System.out.println(arr[i+1]); break; } } } O(n) time and O(1) space ;please share your thoughts.
Here is the simple solution with hashmap in O(n) time. #include<iostream> #include<map> using namespace std; int main() { int a[]={1,3,2,7,5,1,8,3,6,10}; map<int,int> mp; for(int i=0;i<10;i++){ if(mp.find(a[i]) == mp.end()) mp.insert({a[i],1}); else mp[a[i]]++; } for(auto i=mp.begin();i!=mp.end();++i){ if(i->second > 1) cout<<i->first<<" "; } }
int[] a = {5, 6, 8, 9, 3, 4, 2, 9 }; int[] b = {5, 6, 8, 9, 3, 6, 1, 9 }; for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) { Console.Write("Original Array manipulated at position {0} + "\t\n" + "and the element is {1} replaced by {2} ", i, a[i],b[i] + "\t\n" ); break; } } Console.Read(); ///use break if want to check only one manipulation in original array. ///If want to check more then one manipulation in original array, remove break
This video If Programming Was An Anime is too fun not to share. It is the same problem and the video has the answers: Sorting Creating a hashmap/dictionary. Creating an array. (Though this is partially skipped over.) Using the Tortoise and Hare Algorithm. Note: This problem is more of a trivia problem than it is real world. Any solution beyond a hashmap is premature optimization, except in rare limited ram situations, like embedded programming. Furthermore, when is the last time you've seen in the real world an array where all of the variables within the array fit within the size of the array? Eg, if the data in the array is bytes (0-255) when do you have an array 256 elements or larger without nulls or inf within it, and you need to find a duplicate number? This scenario is so rare you will probably never get to use this trick in your entire career. Because it is a trivia problem and is not real world the question, I'd be cautious accepting an offer from a company that asks trivia questions like this, because people will pass the interview by sheer luck instead of skill. This implies the devs there are not guaranteed to be skilled, which unless you're okay teaching your seniors skills, you might have a bad time.
int a[] = {2,1,2,3,4}; int b[] = {0}; for(int i = 0; i < a.size; i++) { if(a[i] == a[i+1]) { //duplicate found //copy it to second array b[i] = a[i]; } }