Need help in understanding the logic for the algorithm [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
There was an online coding event yesterday on Codechef, and I can't figure out how to solve one of the questions from it. Briefly put:
Given a list of N numbers { a1, a2, …, aN }, find the range [L, R] (1 ≤ L ≤ R ≤ N) that maximizes the sum (a1 + … + aL−1) − (aL + … + aR) + (aR+1 + … + aN).
In other words, you get to multiply a subsection of the list by −1, and want to maximize the sum of the resulting list.
I looked at few of the solution like this but couldn't figure out what this guy is doing.
How would I go about this?
EXAMPLE
-2 3 -1 -4 -2
Now you can multiply the subsection 3 to 5 by -1 to get
-2 3 1 4 2
such that the sum(-2,3,1,4,2) = 8 which is the maximum possible for this case

if we can find the minimum sequence from the array than that part if we multiply with one will give you max sum.
For example in this example : -2 3 -1 -4 -2 the minimum sequence is -1, -4, -2. if we multiply this sequence with one it will maximise the sum. So the question is how to find minimum sum sequence.
Here come the O(N) solution:
negate every number
and run the kadane's algorithm
If the array contains all +ve than no subarray which needs to be multiplied by -1. Check the below question. minimum sum subarray in O(N) by Kadane's algorithm

The algorithm you have shown basically calculates the maximum sum and current sum up to any element.
Note: It builds the array with opposite sign of the original elements.
If the current sum is negative, then it rejects the original sum and starts a new sum with the new element.
If the current sum is positive, then that means including the previous entries is beneficial and it adds the current element to the sum.

If I understand your problem correctly, it sounds like you want to first find the minimum subarray and then multiply that by -1 and add the remaining non negated values.
The minimum subarray is essentially the opposite of maximum subarray problem:
public class MaxSumTest {
public static class MaxSumList{
int s=0, e=0;
List<Integer> maxList;
public MaxSumList(List<Integer> l){
//Calculate s and e indexes
minSubarray(l);
//Negate the minSubarray
for(int i=s; i < e; i++)
l.set(i, -l.get(i));
//Store list
maxList = l;
}
public int minSubarray(List<Integer> l){
int tmpStart = s;
int currMin = l.get(0);
int globalMin = l.get(0);
for(int i=1; i<l.size(); i++){
if(currMin + l.get(i) > 0){
currMin = l.get(i);
tmpStart = i;
}
else{
currMin += l.get(i);
}
if(currMin < globalMin){
globalMin = currMin;
s = tmpStart;
e = i+1;
}
}
return globalMin;
}
}
public static void main(String... args){
MaxSumList ms = new MaxSumList(Arrays.asList(new Integer[]{-2, 3, -1, -4, -2}));
//Prints [-2, 3, 1, 4, 2]
System.out.println(ms.maxList);
}
}

Related

Power hungry google foobar challenge fails 4th test case [closed]

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 1 year ago.
Improve this question
I have submitted the test already so this isn't violation of Stack Overflow guidelines.
I have been trying to solve this google foobar question Power Hungry which reads as:
Commander Lambda's space station is HUGE. And huge space stations take a LOT of power. Huge space stations with doomsday devices take even more power. To help meet the station's power needs, Commander Lambda has installed solar panels on the station's outer surface. But the station sits in the middle of a quasar quantum flux field, which wreaks havoc on the solar panels. You and your team of henchmen have been assigned to repair the solar panels, but you'd rather not take down all of the panels at once if you can help it, since they do help power the space station and all!
You need to figure out which sets of panels in any given array you can take offline to repair while still maintaining the maximum amount of power output per array, and to do THAT, you'll first need to figure out what the maximum output of each array actually is. Write a function solution(xs) that takes a list of integers representing the power output levels of each panel in an array, and returns the maximum product of some non-empty subset of those numbers. So for example, if an array contained panels with power output levels of [2, -3, 1, 0, -5], then the maximum product would be found by taking the subset: xs[0] = 2, xs[1] = -3, xs[4] = -5, giving the product 2*(-3)*(-5) = 30. So solution([2,-3,1,0,-5]) will be "30".
Each array of solar panels contains at least 1 and no more than 50 panels, and each panel will have a power output level whose absolute value is no greater than 1000 (some panels are malfunctioning so badly that they're draining energy, but you know a trick with the panels' wave stabilizer that lets you combine two negative-output panels to produce the positive output of the multiple of their power values). The final products may be very large, so give the solution as a string representation of the number.
Languages
To provide a Python solution, edit solution.py
To provide a Java solution, edit Solution.java
Test cases
Your code should pass the following test cases.
Note that it may also be run against hidden test cases not shown here.
-- Python cases --
Input:
solution.solution([2, 0, 2, 2, 0])
Output:
8
Input:
solution.solution([-2, -3, 4, -5])
Output:
60
-- Java cases --
Input:
Solution.solution({2, 0, 2, 2, 0})
Output:
8
Input:
Solution.solution({-2, -3, 4, -5})
Output:
60
I wrote the below code in Java
public static String solution(int[] xs) {
// Your code here
// for(int i:xs)System.out.println(i);
int n=xs.length;
if(n==1){
return String.valueOf(xs[0]);
}
int neg=0,z=0,ans=1,m_neg=Integer.MIN_VALUE;
for(int i:xs){
if(i<0){
neg++;
m_neg=m_neg>i?m_neg:i;
}
}
for(int i:xs){
if(i==0){
z++;
continue;
}
if(neg%2==1 && i==m_neg){
ans*=1;
}
else{
ans*=i;
}
}
if(z==n) return "0";
if(neg%2==1){
if(neg==1 && z>0 && z+neg==n) return "0";
}
return ans>0?String.valueOf(ans):"0";
}
One of the test cases (4th one to be precise) is failing. I tried various edge cases but I can't pass that.
Can anyone explain what did I miss?
You can do this with single loop:
Iterate over the array
Keep multiplying with non zero elements
Keep tracking the smallest value negative integer at the same time.
If at the end product is negative then divide by the small value integer.
Like this:
public class Test {
public static void main(String[] args) throws Exception {
int[] arr = {-2, -3, 4, -5};
System.out.println(solution(arr));
}
public static String solution(int[] xs) {
BigInteger ans = BigInteger.valueOf(1);
int min = Integer.MIN_VALUE;
for (int i = 0; i < xs.length; i++) {
int j = xs[i];
if(j>0)
ans = ans.multiply(BigInteger.valueOf(j));
else if(j<0) {
if(min<j) min = j;
ans = ans.multiply(BigInteger.valueOf(j));
}
}
if(ans.compareTo(BigInteger.ZERO)<0) {
ans = ans.divide(BigInteger.valueOf(min));
}
return ans.toString();
}
}
Output:
60
Note: this is just a demo. Fix or improve the code as per your needs.
My algorithm is as follows:
Sort the array.
Count the number of negative integers in the array.
If there is an odd number of negative integers in the array, save the index of the largest negative number. (In the array {-2, -3, 4, -5} the largest negative integer is -2.)
Iterate the array and multiply all the elements together, skipping elements that are 0 (zero) and skipping the largest negative integer (only if there are an odd number of negative integers in the array).
/*
import java.math.BigInteger;
import java.util.Arrays;
*/
public static String solution(int[] xs) {
String result = "0";
if (xs != null && xs.length > 0) {
if (xs.length == 1 && xs[0] <= 0) {
return result;
}
Arrays.sort(xs);
int i = 0;
while (xs[i++] < 0) {
}
if (--i % 2 == 1) {
--i;
}
else {
i = -1;
}
BigInteger product = new BigInteger("1");
int count = 0;
for (int j = 0; j < xs.length; j++) {
if (xs[j] != 0 && j != i) {
count++;
product = product.multiply(new BigInteger(String.valueOf(xs[j])));
}
}
if (count > 0) {
result = product.toString();
}
}
return result;
}
I use BigInteger to store the result since, as stated in the question, the result may be very large.

Assistance with array lab [closed]

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 am in a intro to Java class. I seem to be having trouble figuring out the algorithm for how i want to go about this.
Currently I need to create and application that generates the number to store in an array element by summing its index and the individual digits of the index. For example, the element with index 17 should be stored as 25... (17+1+7=25) and an element with index 2 would store as 4 (2+0+2=4). I need the program to have 101 elements and then display each value.
I seem to be having trouble figuring out the algorithm for how i want to go about this. Any assistance in the matter would be greatly appreciated.
Thanks in advance. I currently am still researching this matter and am still learning to code so please bear with me.
This is the updated code that I have come up with so far
import java.util.Random;
public class Java_Lab_4 {
public static void main(String[] args) {
int size = 101;
int max = 101;
int[] array = new int[size];
int loop = 0;
Random generator = new Random();
//Write a loop that generates 101 integers
//Store them in the array using generator.nestInt(max);
generator.nextInt(max);
for (int i = 0; i<101; i++)
{
generator.nextInt(max);
}
}
There are surely many ways to achieve this, but the easiest would be repeated division by 10 (another way would be modular arithmetic, taking the index modulo 10).
This means that you would arrive at something like the following algorithm:
int n = i; // i is the index of the current item
while (n > 0) {
int x = n;
if (x > 10) { // we need to deal with the case where i is small
x = n / 10;
}
while (x > 10) { // necessary because we may be dealing with an index > 100
x = x / 10;
} // at this point we have the first digit of the index
a[i] += x; // add this digit to a[i]
n = n / 10; // get rid of the above digit in the calculation. Note that if n < 10, integer division means that n / 10 == 0
} // at the end of this loop, we have added all digits of i to a[i]
a[i] += i; / now we only need to add the index value itself
There are many ways to solve this, and this is a very straightforward and basic approach. I've added ample comments, but please try to work through the code to understand why this works rather than just copying it.
Without posting complete code -- because this is an assignment -- here are some things to consider:
array[a] = a + a;
would give you the solution for indices where a < 10. For two/three digit indices, you need to extract the digits with for example
int nthDigit = Integer.parseInt( // Finally, converts the single-char String to an int
String.valueOf( // converts the char matching the digit to a String
String.valueOf(a).charAt(n))); // converts 'a' first to a String and
// then takes its 'n'th character
where n is 0, 1 or 2. The values of these would then need to be added to the value of the index (a).

product of the numbers in list in java

My task here is to find the minimal positive integer number say 'A' so that the product of digits of 'A' is exactly equal to N.
example: lets say my N = 32
so my A would be 48 coz the divisors of 32 would be 1,2,4,8,16,32 and the minimum numbers that would make 32 is 4 and 8. so output is 48.
what i did is first read N, then found the divisors and stored them in a list. and used
if(l.get(i)*l.get(i+1)==N) {
sysout.print(l.get(i));
sysout.print(l.get(i+1));
but im not able to make the numbers as minimum. and also i need to print as -1 if no match is found.
for that i did:
if (l.get(i)*l.get(i+1)!=N) {
System.out.print(-1);
break;
}
but it is printing -1 initially only and breaking off. now im stuck here. please find my code below:
my code:
int N=1;
Scanner in = new Scanner(System.in);
List<Integer> l = new ArrayList<Integer>();
System.out.println("Enter N: ");
if (N>=0 && N<=Math.pow(10, 9)) {
N = in.nextInt();
}
for (int i=1; i<=N;i++) {
if (N%i==0) {
l.add(i);
}
}
System.out.println(l);
for (int i=0; i<l.size()-1;i++) {
if (l.get(i)*l.get(i+1)==N) {
System.out.print(l.get(i));
System.out.print(l.get(i+1));
}
}
in.close();
kindly help. thanks.
You're on the right track with finding the divisors on N. I'm not going to code it for you(you'll learn more by doing) but here's what you do: The divisors will be sorted already so loop the arraylist adding first to last and finding the min.
So for 1,2,4,8,16,32: Find 1+32, 2+16, 4+8; And then fin the max among these.
This is to get you started:
int first = 0;
int last = l.size()-1;
while(first<last){
//Find min using Math.min;
++first;
--last;
}
Happy Coding!
Could not resist. Below is a quick way to do what you want. Tested it here
(https://ideone.com/E0f4X9):
public class Test {
static ArrayList<Integer> nums = new ArrayList<>();
public static void main(String[] args){
int N =32;
findDivisors(N);
int first = 0, a = 0, b = 0;
int last = nums.size()-1;
int results = Integer.MAX_VALUE;
while(first < last){
int sum = nums.get(first) + nums.get(last);
results = Math.min(sum,results);
a = nums.get(first);
b = nums.get(last);
first++;
last--;
}
System.out.println(a+" "+b);
}
private static void findDivisors(int n){
for(int i=1; i<=n; i++){
if(n%i == 0){
nums.add(i);
}
}
}
}
Obviously if N<10 then A=N.
Otherwise A has to consist of more than one digit. Every digit of A is a divisor of N. The more significant digits of A always have to be less or equal than the lesser significant digits. Otherwise the order of digits could be changed to produce a smaller number.
For example A could not be 523 because the digits could be rearranged into 235 which is a smaller number. In this example we have 2 < 3 < 5.
Observation #1: when looking at A the smallest digits are at the front, the digits get higher towards the end.
Observation #2, A can never contain two digits a and b if the product of a and b is also a digit. For example, there can never be a 2 and a 3, there would have to be a 6 instead. There could never be three 2s, it would have to be an 8 instead.
This suggests that when building A we should start with the highest possible divisors of N (because a 9 is always better than two 3s, and so on). Then we should put that digit at the end of A.
So, while N > 10, find the highest divisor x of N that is a single digit (2<=x<=9). Add this value x to the end of A. Divide N by x and proceed with the loop.
Example:
N=126, A=?
Highest possible divisor x that is less or equal to 9 is 9. So 9 is going to be the last digit of A.
Divide N by 9 and repeat the process. N=126/9=14.
Now N=14, A=?9
Highest possible divisor x that is less or equal to 9 is 7. We have found the second to last digit of A.
Divide N by 7 and repeat the process. N=14/7=2.
Now N=2, A=?79
N<10. So 2 is the first digit of A.
The solution is A=279

Fibbonacci sequence using for loop java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Can someone explain to me how to store the previous two fibbonnaci numbers it would help alot in this problem.
public static void main(String[] args) {
int k = 0;
for (int x = 1; x < 13; x++) {
if (k > 2) {
k = (k - 1) + (k - 2);
}
System.out.print(k+" ");
k++;
}
}
when you got number 5 as the printed out put you will set k++ , that will make k=6.
after that k = (k - 1) + (k - 2); output k = (6-1)+(6-2) = 5+4 = 9 , (note : the next should be 8 so your algorithm is wrong)
You have mistaken the Idea of Fibonacci numbers.
the nth Fibonacci number is equal to the sum of previous two Fibonacci numbers. not to the (Fn-1)+(Fn-2)
Edited :
So as you can see if we know the first 2 Fibonacci numbers we can calculate the third by adding those two. and the fourth one will be the summation of second one and third one and it goes ..... to n.
Okay here is a way that you don't need a recursive approach ( you need to store the found Fibonacci numbers in an Array)
okay assume you want to find first n Fibonacci numbers. then create an array of size n and set first and second elements to one (1) since first two Fibonacci numbers are 1 and 1. now loop through the array from 2 to n. at each iteration add the previous two element to the next element.
go through the code. you will find it very easy to do.
public static void fib(int n){
int Fibonacci [] = new int[n];
Fibonacci [0]=1;
Fibonacci [1]=1;
for (int i = 2; i < n; i++) {
Fibonacci [i]=Fibonacci [i-1]+Fibonacci [i-2];
}
System.out.println(Arrays.toString(Fibonacci ));
}

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];
}
}

Categories

Resources