i don't understand what is the way to access the data in the array and use it as a condition the condition is to stop looping after the content exceeds 4,000,000 and also store and add the value if its value is an even number!
int[] a=new int[40];
int add=0;
a[0]=1;
a[1]=2;
int i=2;
do{
a[i]=a[i-1]+a[i-2];
System.out.println(a[i]);
if(a[i]%2==0)
{
add=add+a[i];
}
i++;
}
while(i<32);
System.out.println(add);
Just put a check for your variable add to see if its value is greater than 4,000,000 and break out of the loop. Do something like this:
if(add > 4000000) {
break;
}
So your final code will look like this:
int[] a=new int[40];
int add=0;
a[0]=1;
a[1]=2;
int i=2;
do{
a[i]=a[i-1]+a[i-2];
System.out.println(a[i]);
if(a[i]%2==0){add=add+a[i];}
if(add > 4000000) {
break; //this will get you out of your loop
}
i++;
}while(i<32);
System.out.println(add);
I would just throw this out there: Using a do-while loop may be making this harder than it has to be. The first part of your code is totally reasonable, but the while i > 32 is less than clear.
I'd look at it this way. After you initialize your array and its first two values with
int[] a = new int[40];
a[0] = 1;
a[1] = 2;
You know that you've accounted for one even value (2). So just initialized add to 2.
Now for the loop. You want to start at i = 2, and iterate as long as add is less than or greater than 4,000,000, right? So make a for loop to express it:
for (int i = 2; add <= 4000000; i++) {
a[i] = a[i - 2] + a[i -1];
if (a[i] % 2 == 0) {
add += a[i];
}
}
No need for the i < 32, and no need for any break statements!
As a matter of interest, this is a good application for Java 8 streams.
class Fib implements IntSupplier {
private int current = 1;
private int previous = 0;
public int getAsInt() {
int next = current + previous;
previous = current;
current = next;
return current;
}
IntStream.generate(new Fib())
.limit(4000000)
.filter(n - > n % 2 == 0)
.sum();
Related
I'm trying to solve the problem below from CodeFights. I left my answer in Java after the question. The code works for all the problems, except the last one. Time limit exception is reported. What could I do to make it run below 3000ms (CodeFights requirement)?
Note: Write a solution with O(n) time complexity and O(1) additional space complexity, since this is what you would be asked to do during a real interview.
Given an array a that contains only numbers in the range from 1 to a.length, find the first duplicate number for which the second occurrence has the minimal index. In other words, if there are more than 1 duplicated numbers, return the number for which the second occurrence has a smaller index than the second occurrence of the other number does. If there are no such elements, return -1.
Example
For a = [2, 3, 3, 1, 5, 2], the output should be
firstDuplicate(a) = 3.
There are 2 duplicates: numbers 2 and 3. The second occurrence of 3 has a smaller index than than second occurrence of 2 does, so the answer is 3.
For a = [2, 4, 3, 5, 1], the output should be
firstDuplicate(a) = -1.
Input/Output
[time limit] 3000ms (java)
[input] array.integer a
Guaranteed constraints:
1 ≤ a.length ≤ 105,
1 ≤ a[i] ≤ a.length.
[output] integer
The element in a that occurs in the array more than once and has the minimal index for its second occurrence. If there are no such elements, return -1.
int storedLeastValue = -1;
int indexDistances = Integer.MAX_VALUE;
int indexPosition = Integer.MAX_VALUE;
for (int i = 0; i < a.length; i++)
{
int tempValue = a[i];
for (int j = i+1; j < a.length; j++) {
if(tempValue == a[j])
{
if(Math.abs(i-j) < indexDistances &&
j < indexPosition)
{
storedLeastValue = tempValue;
indexDistances = Math.abs(i-j);
indexPosition = j;
break;
}
}
}
}
return storedLeastValue;
Your solution has two nested for loops which implies O(n^2) while the question explicitly asks for O(n). Since you also have a space restriction you can't use an additional Set (which can provide a simple solution as well).
This question is good for people that have strong algorithms/graph theory background. The solution is sophisticated and includes finding an entry point for a cycle in a directed graph. If you're not familiar with these terms I'd recommend that you'll leave it and move to other questions.
Check this one, it's also O(n) , but without additional array.
int firstDuplicate(int[] a) {
if (a.length <= 1) return -1;
for (int i = 0; i < a.length; i++) {
int pos = Math.abs(a[i]) - 1;
if (a[pos] < 0) return pos + 1;
else a[pos] = -a[pos];
}
return -1;
}
The accepted answer does not work with the task.
It would work if the input array would indeed contain no bigger value than its length.
But it does, eg.: [5,5].
So, we have to define which number is the biggest.
int firstDuplicate(int[] a) {
int size = 0;
for(int i = 0; i < a.length; i++) {
if(a[i] > size) {
size = a[i];
}
}
int[] t = new int[size+1];
for(int i = 0; i < a.length; i++) {
if(t[a[i]] == 0) {
t[a[i]]++;
} else {
return a[i];
}
}
return -1;
}
What about this:
public static void main(String args[]) {
int [] a = new int[] {2, 3, 3, 1, 5, 2};
// Each element of cntarray will hold the number of occurrences of each potential number in the input (cntarray[n] = occurrences of n)
// Default initialization to zero's
int [] cntarray = new int[a.length + 1]; // need +1 in order to prevent index out of bounds errors, cntarray[0] is just an empty element
int min = -1;
for (int i=0;i < a.length ;i++) {
if (cntarray[a[i]] == 0) {
cntarray[a[i]]++;
} else {
min = a[i];
// no need to go further
break;
}
}
System.out.println(min);
}
You can store array values in hashSet. Check if value is already present in hashSet if not present then add it in hashSet else that will be your answer. Below is code which passes all test cases:-
int firstDuplicate(int[] a) {
HashSet<Integer> hashSet = new HashSet<>();
for(int i=0; i<a.length;i++){
if (! hashSet.contains(a[i])) {
hashSet.add(a[i]);
} else {
return a[i];
}
}
return -1;
}
My simple solution with a HashMap
int solution(int[] a) {
HashMap<Integer, Integer> countMap = new HashMap<Integer, Integer>();
int min = -1;
for (int i=0; i < a.length; i++) {
if (!(countMap.containsKey(a[i]))) {
countMap.put(a[i],1);
}
else {
return a[i];
}
}
return min;
}
Solution is very simple:
Create a hashset
keep iterating over the array
if element is already not in the set, add it.
else element will be in the set, then it mean this is minimal index of first/second the duplicate
int solution(int[] a) {
HashSet<Integer> set = new HashSet<>();
for(int i=0; i<a.length; i++){
if(set.contains(a[i])){
// as soon as minimal index duplicate found where first one was already in the set, return it
return a[i];
}
set.add(a[i]);
}
return -1;
}
A good answer for this exercise can be found here - https://forum.thecoders.org/t/an-interesting-coding-problem-in-codefights/163 - Everything is done in-place, and it has O(1) solution.
I'm trying to loop through my array to find the maximum value and print the value. However, nothing is being printed to the console. Can you please take a look at my code below to see what I've done incorrectly.
for (c = 0; c < n; c++) //loops through array until each index has had a value input by the user
array[c] = in.nextInt();
maxInt = array[0];
minInt = array[0];
for (c = 0; c < n; c++) {
if (array[c] > maxInt) {
maxInt = array[c];
}
else {
break;
}
}
System.out.println("Max int is: " + maxInt);
}
EDIT:
Full class:
import java.util.Scanner;
public class MaxMinOfArray {
public static void main(String[] args) {
int c, n, search, array[];
int maxInt, minInt;
Scanner in = new Scanner(System.in);
System.out.println("Enter number of elements");
n = in.nextInt(); //asks user to specify array size
array = new int[n]; //creates array of specified array size
System.out.println("Enter " + n + " integers");
for (c = 0; c < n; c++) //loops through array until each index has had a value input by the user
array[c] = in.nextInt();
maxInt = array[0];
minInt = array[0];
for (c = 1; c < n; c++) {
if (array[c] > maxInt) {
maxInt = array[c];
}
}
System.out.println("Max int is: " + maxInt);
}
}
Remove:
else {
break;
}
And start from c=1
Remove your this part of code.
else {
break;
}
Because when c==0 in that time array[c] == maxInt. So it goes to else part and break your for loop.
As others indicated, you don't want to do
else {
break;
}
That means that it'll stop looping as soon as it finds a number that isn't larger than the current max. Since you're starting with the first item in the list, which trivially isn't larger than itself, you break immediately.
Even if you changed it to start at c = 1, the only case where this code could possibly work as written is if the user entered numbers in ascending order. (In that case, doing a linear search like this would be pointless anyway since you could literally just find the last item in the array and know that it'll be the largest item).
Also, you should check to see if array[c] is smaller than the current minimum value in your for loop; there's no reason at all to do this in a separate loop.
Remember, if you're doing a linear search for the max value of an unsorted array, you always must go through the entire array to make sure you didn't miss a greater value. For example, if you only search half of the array, how do you know that the half that you didn't search doesn't contain the max value?
Your second loop compares for each element in array if it is greater than maxInt, but maxInt has just been set to the first element of array. This fails the condition on the first iteration of the loop, executing the break in the else block, which ends the loop.
Taking out the else block fixes this:
for (c = 0; c < n; ++c)
{
if (array[c] > maxInt)
maxInt = array[c];
}
Or alternatively:
for (c = 0; c < n; ++c)
maxInt = Math.max(maxInt, array[c]);
As for the console message not appearing, make sure the code is properly executed by setting a breakpoint and stepping through the code (depends on the IDE you're using).
I have the methods to find the smallest and largest value, and also to place them where they need to be. I also have a method to call those methods, and shrink to a subarray. The problem is, even though it is sorting, I can't print the array once I've moved into the subarray. Please help, there has to be a better way and I've banged my head against the wall for a while now.
package mySort;
import java.util.Arrays;
public class MyAlg {
public static int findSmall(int[] input){
int sm = input[0];
for(int i = 0; i <= input.length - 1; i++){
if(sm < input[i])
sm = input[i];
}
input[0] = sm;
return sm;
}
public static int findLarge(int[] input){
int lg = input[input.length -1];
for(int i = 0; i <= input.length - 1; i++){
if(input[i] > lg)
lg = input[i];
}
input[input.length -1] = lg;
return lg;
}
public static int[] sort(int[] input){
findSmall(input);
findLarge(input);
for(int i = 0; i<= (input.length - 1) / 2; i++){
int[] tmp = Arrays.copyOfRange(input, i + 1, input.length - 2 );
findSmall(tmp);
findLarge(tmp);
}
}
}
I am not sure if you are required to use an array or not, but if you are free to use whatever data structure you like I would recommend a TreeSet. This data structure implements SortedSet which means as the objects are added they are sorted already for you. Then you can use methods such as
first() - to return the lowest value
last() - to return the highest value
Then you could remove those highest and lowest elements or use these methods after that
ceiling(int) - highest number lower than given int
floor(int) - smallest number higher than given int
Lmk if you need more help or just need an implementation for an array.
Unfortunately your code is quite flawed, so I just rewrote everything. The below code will sort any int[] by placing the smallest int in the input array in the left most unfilled position of a new array and placing the biggest in the right most unfilled position of a new array, until the new array is a sorted version of the input array. Enjoy
private static int[] sort(int[] input) {
//create an empty array the same size as input
int[] sorted = new int[input.length];
//create another empty array the same size as input
int[] temp = new int[input.length];
// copy input into temp
for (int i = 0; i <= (input.length - 1); i++) {
temp[i] = input[i];
}
//create variables to tell where to put big and small
//in the sorted array
int leftIndex = 0;
int rightIndex = sorted.length - 1;
//create variables to hold the biggest and smallest values in
//input. For now we'll give them the values of the first element
//in input, they'll change
int big = input[0];
int small = input[0];
// sort
//sort the array as you described
while (temp.length != 0) {
//find the biggest and smallest value in temp
big = findBig(temp);
small = findSmall(temp);
//place the biggest at the end of the sorted array
//and place the smallest at the beginning of the sorted array
sorted[leftIndex] = small;
sorted[rightIndex] = big;
//move the left index of the sorted array up, so we don't over write
//the element we put in on the next iteration, same for the right index to,
//but down
leftIndex++;
rightIndex--;
if(temp.length != 1){
//remove the biggest and smallest values from the temp array
temp = removeElement(temp, big);
temp = removeElement(temp, small);
}else{
//only remove one element in the event the array size is odd
//also not at this point leftIndex == rightIndex as it will be the last
//element
temp = removeElement(temp, big);
}
//repeat, until the temp array is empty
}
// print out the content of the sorted array
for (int i = 0; i <= (sorted.length - 1); i++) {
System.out.println("Index " + i + ": " + sorted[i]);
}
//return the sorted array
return sorted;
}
//find the smallest number in an int array and return it's value
private static int findSmall(int[] input) {
int smallest = input[0];
for (int i = 0; i <= (input.length - 1); i++) {
if (smallest > input[i]) {
smallest = input[i];
}
}
return smallest;
}
//find the biggest value in an int array and return it's value
private static int findBig(int[] input) {
int biggest = input[0];
for (int i = 0; i <= (input.length - 1); i++) {
if (biggest < input[i]) {
biggest = input[i];
}
}
return biggest;
}
//remove an element from an int array, based on it's value
private static int[] removeElement(int[] input, int elementValue) {
//create a temp array of size input - 1, because there will be one less element
int[] temp = new int[input.length - 1];
//create variable to tell which index to remove, set to 0 to start
//will change unless it is right
int indexToRemove = 0;
//find out what the index of the element you want to remove is
for (int i = 0; i <= (input.length - 1); i++) {
if (input[i] == elementValue) {
//assign the value to
indexToRemove = i;
break;
}
}
//variable that says if we've hit the index we want to remove
boolean removeFound = false;
for (int i = 0; i <= (input.length - 1); i++) {
//check if we are at the index we want to remove
if (indexToRemove == i) {
//if we are say so
removeFound = true;
}
//done if we aren't at the index we want to remove
if (i != indexToRemove && removeFound == false) {
//copy input to temp as normal
temp[i] = input[i];
}
//done if we've hit the index we want to remove
if (i != indexToRemove && removeFound == true) {
//note the -1, as we've skipped one and need the to decrement
//note input isn't decremented, as we need the value as normal
//note we skipped the element we wanted to delete
temp[i - 1] = input[i];
}
}
//return the modified array that doesn't contain the element we removed
//and it is 1 index smaller than the input array
return temp;
}
}
Also, I'd place all of these methods into a class Sort, but I wrote it in this way to mimic the way you wrote your code to a certain extent. This would require you to create a getSorted method, and I'd also change the sort method to a constructor if it was placed in a class Sort.
I have written an algorithm to solve your this problem. Using divide and conquer we can solve this problem effectively. Comparing each value to every one the smallest and the largest value can be found. After cutting off 2 values the first one(smallest) and the last one (largest) the new unsorted array will be processed with the same algorithm to find the smallest and largest value.
You can see my algorithm in [GitHub] (https://github.com/jabedhossain/SortingProblem/)
Although its written in C++, the comments should be enough to lead you through.
I have written a program to place all even elements of the array to the left and odd ones to the right half of the array. The order of elements is not of concern. I was wondering if there is more efficient algorithm than this. My worst case complexity is O(n/2). Here is the code.
// Program to shift all even numbers in an array to left and odd to the right. Order of digits is not important.
import java.util.*;
import java.lang.*;
import java.io.*;
class Rearrange
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int[] array = new int[] {1,2,3,4,5,6,7};
// keep two pointers.
int odd, even;
odd = 0;
even = array.length-1;
int i;
// Code to re-arrange the contents of the array
i=0;
while(i<array.length){
if(array[i]%2!=0){
odd = i;
break;
}
i++;
}
i=array.length-1;
while(i>=0){
if(array[i]%2==0){
even = i;
break;
}
i--;
}
while(odd<even){
if((array[odd]%2!=0) && (array[even]%2==0)){
// swap contents
array[odd] = array[odd] + array[even];
array[even] = array[odd] - array[even];
array[odd] = array[odd] - array[even];
odd++;
even--;
}
else if(array[odd]%2==0){
odd++;
}
else if(array[even]%2!=0){
even--;
}
else
continue;
}
for(int val : array)
System.out.println(val+" ");
}
}
For any algorithm without sufficient information about structure of data you cannot do it in less than O(N) where N is the input size because if you do it faster that means you are not considering a part of the input hence algorithm might be incorrect.
Here is in-place code for you problem :-
int i=0,j=n-1;
while(i<j) {
if(arr[i]%2==0) {
i++;
}
else {
swap(arr[i],arr[j]);
j--;
}
}
I don't see how is your code O(N/2). If array contains all odd or all even then one of the while loop will iterate through all n elements.
Instead of splitting code like you have done to get first odd/even numbers you can do something like quick sort, pivot element being last element and instead of separating less than and greater than you can check your criteria.
int i = 0;
int j = arr.length -1;
while(i < j){
if(arr[i]%2 != 0){
i++;
}
if(arr[j]%2 == 0){
j--;
}
//swap
arr[i] = arr[i] + arr[j];
arr[j] = arr[i] - arr[j];
arr[i] = arr[i] - arr[j];
}
I have a java question.
I have two int[] arrays: cdn and cmn.
cdn is {1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
cmn is {8,8,16}
I need a program that adds the consecutive integers of cdn[] upto cmn[init] and returns the number of integers used in the addition. Then it continues adding from the next integer of cdn[] upto cmn[init+1] and return the number of integers. For the arrays above this is done 3 times: the first time the return value is 7, the second time it is 7, and the third time it is 16. The number of integers can be collected in and int[] which is {7,7,16}. The code I have is:
int numofints = 0;
int init = 0;
int plus = 0;
while(init < m2){
for(int j = 0; j < cdn.length; j++){
plus += cdn[j];
numofints++;
if(plus == cmn[init]){
init++;
}
}
}
System.out.print(numofints);
in which m2 is the size of cmn, which is 3 in this case. Note that my program starts to loop from the beginning of cdn over and over again, because j = 0. I want it to start where it ended the previous time!
I hope you have a solution for me.
Bjorn
just pull j out of the outer loop, and use a while, instead of for, for the inner loop
and you also need to put plus = 0 into the loop
public class T {
public static void main(String[] args) {
int[] cdn = {1,1,1,1,1,1,2,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int[] cmn = {8,8,16};
int numofints = 0;
int init = 0;
int m2 = 3;
int j = 0;
while(init < m2){
int plus = 0;
while(j < cdn.length){
plus += cdn[j];
j++;
numofints++;
if(plus == cmn[init]){
init++;
System.out.println(j);
break;
}
}
if (j == cdn.length) break;
}
}
}
Shoudln't if(plus == cmn[init]){ be if(plus >= cmn[init])? If you change cdn at all and "plus" happens to go over "cmn[init]", your code is going to break.