Related
I was looking over some basic questions that might be asked in an interview. Using basic for loops (No hash maps etc)I want to sum up all the matching elements in an array.For example, 6 matching elements will result in (Matched: 6) and a total of 36 in the example below.An example of this could be rolling dice, and the score is the total of all the dice that match.
public static void main(String[] args) {
int arr[] = {6,6,6,6,6,6};
int matched = 1;
int value = 0;
int total = 0;
for(int i=0;i<arr.length;i++){
for(int j=(i+1);j<arr.length;j++){
if(ar[i] == ar[j]){
matched++;
value = ar[i];
break;
}
}
total = (matched * value);
} // End for loop
System.out.println("Matched:"+(matched)+"");
System.out.println("Total:"+total);
}
But, if the array was for example...
int arr[] = {6,1,1,6,6,6};
The output I get will be (Matched:5) and an a total of 30.Can could I store the matching pair of 1's and add them to the total using as little basic code as possible?
Interpreting the question as "provide the total number of values that occur more than once and their sum", and taking into account that nothing "fancy" (sic) such as a map can be used:
int[] array = {6, 1, 1, 6, 6, 6};
int sum = 0;
int matches = 0;
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (i != j && array[i] == array[j]) {
sum += array[i];
matches++;
break;
}
}
}
System.out.println(matches); // 6
System.out.println(sum); // 26
If you are allowed to use arrays - if not too fancy - then you could use 3 loops:
The first finds minimum and maximum elements
The second determines the occurrence of each item
The third calculates the totals
In Java this would look like this:
public static void main(String[] args) {
int[] array = {6, 3, 3, 6, 6, 6, 4, 4, 20};
int min = array[0];
int max = array[0];
// Find min max
for (int i : array) {
if (i < min) {
min = i;
}
if (i > max) {
max = i;
}
}
// Use array to sum up all elements
int[] holderArray = new int[max - min + 1];
for (int i : array) {
holderArray[i - min]++;
}
// Calculate occurrence and sums
for(int i = 0; i < holderArray.length; i++) {
if(holderArray[i] > 0) {
System.out.printf("number: %2d; count: %2d; sum: %2d%n", i + min, holderArray[i], (i + min) * holderArray[i]);
}
}
}
This prints out:
number: 3; count: 2; sum: 6
number: 4; count: 2; sum: 8
number: 6; count: 4; sum: 24
number: 20; count: 1; sum: 20
I don't completely understand your question, but based from what I understood, you want to get the sum of all matched numbers if its greater than 1? In that case there is a O(n) solution that you could use.
Create an empty Map then iterate over the array, and if the current number is not within the map add it to the map with value 1, if the current element is already existing in the map then just increment it's value (val++), at the end you will have a map and for each key (each distinct number) you will have the number of matched numbers from the array as the value. All you need to do is iterate over the pairs of key,val multiply each key*val then sum up the multiplied values and you get your correct total. And if you need just the number of matched, you can in another variable sum up just the vals.
So for lets say array [1,1,5,1,5,2,2,5,1], your map will something like:
{1:4, 2:2, 5:3},
and your totals:
total matches: 9
total: 23
I hope this helps!
Here is a code fragment I just wrote. This method takes in an array of integers and creates a map of each unique integer and it's count in the list. In the second part of the method, the HashMap object countOfNumbersMap is iterated and the sum of each element is printed.
private void findSumOfMatchingNumbers(int array[]) {
HashMap<Integer, Integer> countOfNumbersMap = new HashMap<>();
// Setting up the map of unique integers and it's count
for (int i = 0 ; i < array.length ; i++) {
if (countOfNumbersMap.containsKey(array[i])) {
int currentCount = countOfNumbersMap.get(array[i]);
countOfNumbersMap.put(array[i], currentCount + 1);
} else {
countOfNumbersMap.put(array[i], 1);
}
}
for (Integer integer : countOfNumbersMap.keySet()) {
int sum = countOfNumbersMap.get(integer) * integer;
System.out.println(String.format("Number = %d, Sum = %d", integer, sum));
}
}
The worst case runtime of the program is O(n).
If the range of your integers is limited, the easiest way to do this would be to create a histogram (i.e. create an array, where under index i you store the number of occurrences of the number i).
From that, it's easy to find elements that occur more than once, and sum them up. This solution has a complexity of O(n+k), where k is the range of your integers.
Another solution is to sort the array,then the matching numbers will be next to each other, and it's easy to count them. This has O(nlogn) complexity.
If these methods are not allowed, here is a solution in O(n^2) that only uses for loops:
Sum up the whole array
With a double loop, find all elements that are unique, subtract them from the sum, and count their number.
The remaining sum is the sum of all elements occurring more than once, and the count of unique elements subtracted from the length of the array gives the number of matching element.
I need to find the missing number in an array in O(n^2) time. I can rearrenge the array, so it is in order, but I have a difficult time finding the missing number without running another for loop, but I can't do that.
Here is my code:
The missing number is 3 here.
public static void main(String[] args){
int ar []={0,1,6,2,5,7,4};
int n = ar.length;
int temp = 0;
int m = 0;
for(int i = 0; i<n;i++){
for(int j = 1; j<n;j++){
if(ar[j-1] > ar[j]){
temp = ar[j-1];
ar[j-1]=ar[j];
ar[j]=temp;
if(ar[j-1]!=j-1) m=j;
}
else ar[j]=ar[j];
if(ar[j-1]!=j-1) m=j;
}
}
System.out.println(m);
}
If the input array contains all the numbers between 0 and ar.length except one missing number (as in your {0,1,6,2,5,7,4} example), you can find the missing number in linear time.
Just calculate the sum of all the numbers of the full array (the one including the missing number) - that array has ar.length + 1 elements from 0 to ar.length, so its sum is (ar.length - 0)*(ar.length + 1)/2 - and subtract from it the actual sum (which you can compute in a simple linear time loop). The difference would be the missing number.
If there are multiple missing numbers (or there may be duplicate numbers), and you need to find the first missing number, sorting the array in O(n*log(n) time and then making a single (linear time) pass over the sorted array would still be better than an O(n^2) solution.
If you can only do 2 loops, and must do 2 loops for O(n^2), then I suggest the following:
Loop thru all values (outer loop).
For each value, loop thru all values (inner loop) and find smallest value higher than current value.
If no higher value found, skip (current value is highest value)
If smallest value found is not current value + 1, then you found the missing value
How about this?
int array[] = {0,1,6,2,5,7,4};
int arrayTemp[] = array;
ArrayList<Integer> missing = new ArrayList();
Arrays.sort(arrayTemp);
for (int i=1; i<arrayTemp.length; i++) {
for (int j=arrayTemp[i-1]+1; j<arrayTemp[i]; j++) {
missing.add(j);
}
}
for (int i=arrayTemp[arrayTemp.length-1]+1; i<=arrayTemp[arrayTemp.length-1]; i++) {
missing.add(i);
}
System.out.println(missing.toString());
Output:
{0,1,6,2,5,7,4} -> [3]
{0,1,6,2,5,7,4,14} -> [3, 8, 9, 10, 11, 12, 13]
How to print the following sequence using a simple loop in Java
10, 11, 11, 12,12,12,13,13,13,13,14,14,14,14,14
int currentNumber = 10;
int timesToPrint = 1;
int timesPrinted = 0;
while(currentNumber < 15){
System.out.println(currentNumber);
timesPrinted++;
if(timesPrinted == timesToPrint){
timesToPrint++;
timesPrinted = 0;
currentNumber++;
}
}
Well I don't want to do your homework for you, but notice the pattern here. There is 1 10, 2 11s, 3 12s etc....
you need a loop that starts at 10 and ends at 14 which looks like:
for(int i = 10; i<=14; i++){
//print i
}
but instead of just printing i once, you need to print it 1,2,3,4, or 5 times.
One way to do this is to create another variable that starts at 1 and increases every time i increases. Then create another loop nested in the first that prints i that many times. That should be enough to get you started. Feel free to ask questions if you run into trouble.
String s = "";
int timer = 1;
for (int i =10; i<15; i++)
{
for (int a = 0; a<timer; a++)
{
s += i + ", ";
}
timer++;
}
System.out.println(s);
Use this
int num=10;
for(int i=1 ;i<10;i++)
{
for(int j=0;j<i;j++)
{
System.out.print(num+",");
}
num ++;
}
You havent really shown that you have done any work yourself... Anyway
for(int i = 0; i <= 4; i++){
for(int ii = 0; ii <=i; ii++){
int numbertoshow = 10+i;
System.out.print(numbertoshow+", ");
}
}
Output:
10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14,
The first loop specifies what the end digit will be (e.g if i = 0, 10+i = 10, so the output will be 10).
The second loop will make it repeat the output (i) times, (e.g, if i = 2, 10+i = 12, so it will output 12 when ii is equal to 0, 1 and 2, hence 3 times)
You need to have a counter in order to know "How many numbers, did you printed so far".
Let me name it counter. You have to Declare it as an integer
By now, we can see that your string of numbers, has a special order, it seems like: counter%10 + 10 (where % sign is represented Modulo calculation).
So by now you can do the following:
public class Printer { // Create a class which its responsibility is to print requested string
public static void main(String[] args) { // The entry point of almost every java program
int end = 4; // As you want to print until 14
for (int counter = 1; counter <= end; ++counter) { // A for loop counts steps so far
for (int i = 0; i < counter; ++i) { // Here we print the number as many as counter
System.out.print(10 + counter%10 + ","); // System.out.print is a bulit in function which prints the given string
}
}
}
}
Now you can change the value of end in third line, in order to get more numbers as well
Problem H (Longest Natural Successors):
Two consecutive integers are natural successors if the second is the successor of the first in the sequence of natural numbers (1 and 2 are natural successors). Write a program that reads a number N followed by N integers, and then prints the length of the longest sequence of consecutive natural successors.
Example:
Input 7 2 3 5 6 7 9 10 Output 3 this is my code so far and i have no idea why it does not work
import java.util.Scanner;
public class Conse {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int x = scan.nextInt();
int[] array = new int[x];
for (int i = 0; i < array.length; i++) {
array[i] = scan.nextInt();
}
System.out.println(array(array));
}
public static int array(int[] array) {
int count = 0, temp = 0;
for (int i = 0; i < array.length; i++) {
count = 0;
for (int j = i, k = i + 1; j < array.length - 1; j++, k++) {
if (Math.abs(array[j] - array[k]) == 1) {
count++;
} else {
if (temp <= count) {
temp = count;
}
break;
}
}
}
return temp + 1;
}
}
Why two loops? What about
public static int array(final int[] array) {
int lastNo = -100;
int maxConsecutiveNumbers = 0;
int currentConsecutiveNumbers = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == lastNo + 1) {
currentConsecutiveNumbers++;
maxConsecutiveNumbers = Math.max(maxConsecutiveNumbers,
currentConsecutiveNumbers);
} else {
currentConsecutiveNumbers = 1;
}
lastNo = array[i];
}
return Math.max(maxConsecutiveNumbers, currentConsecutiveNumbers);
}
This seems to work:
public static int longestConsecutive(int[] array) {
int longest = 0;
// For each possible start
for (int i = 0; i < array.length; i++) {
// Count consecutive.
for (int j = i + 1; j < array.length; j++) {
// This one consecutive to last?
if (Math.abs(array[j] - array[j - 1]) == 1) {
// Is it longer?
if (j - i > longest) {
// Yup! Remember it.
longest = j - i;
}
} else {
// Start again.
break;
}
}
}
return longest + 1;
}
public void test() {
int[] a = new int[]{7, 2, 3, 5, 6, 7, 9, 10};
System.out.println("Longest: " + Arrays.toString(a) + "=" + longestConsecutive(a));
}
prints
Longest: [7, 2, 3, 5, 6, 7, 9, 10]=3
Since your question has "Problem H" associated with it, I'm assuming you are just learning. Simpler is always better, so it usually pays to break it down into "what has to be done" before starting on a particular road by writing code that approaches the problem with "how can this be done."
In this case, you may be over-complicating things with arrays. A number is a natural successor if it is one greater than the previous number. If this is true, increment the count of the current sequence. If not, we're starting a new sequence. If the current sequence length is greater than the maximum sequence length we've seen, set the max sequence length to the current sequence length. No arrays needed - you only need to compare two numbers (current and last numbers read).
For example:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int N = scan.nextInt();
int maxSequenceLen = 0; // longest sequence ever
int curSequenceLen = 0; // when starting new sequence, reset to 1 (count the reset #)
int last = 0;
for(int i = 0; i < N; i++) {
int cur = scan.nextInt();
if ((last+1) == cur){
++curSequenceLen;
}
else{
curSequenceLen = 1;
}
if (curSequenceLen > maxSequenceLen){
maxSequenceLen = curSequenceLen;
}
last = cur;
}
System.out.println(maxSequenceLen);
Caveat: I'm answering this on a computer that does not have my Java development environment on it, so the code is untested.
I'm not sure I understand this question correctly. The answer's written here assumes that the the natural successors occur contiguously. But if this is not the same then the solution here might not give the correct answer.
Suppose instead of [7 2 3 5 6 7 9 10] the input was [7 2 6 3 7 5 6 9 10] then the answer becomes 2 while the natural successor [5 6 7] is present in the array.
If the input is not sorted we'll have to use a different approach. Like using HashSet
Load the entire array into a HashSet which removes duplicates.
Pick the first value from the HashSet and assigned it to start and end and remove it from the set.
Now decrements start and check if it is present in the HashSet and continue till a particular value for start is not present int the HashSetwhile removing the value being searched from the set.
Do the same for end except that you will have to increase the value of end for each iteration.
We now have to continuous range from start to end present in the set and whose range is current_Max = end - start + 1
In each iteration we keep track of this current_Max to arrive at the longest natural successor for the entire array.
And since HashSet supports Add, Remove, Update in O(1) time. This algorithm will run in O(n) time, where n is the length of the input array.
The code for this approach in C# can be found here
I have a method that is not working properly.
The method is supposed to sort a set of numbers from 1 to 20 randomly (each number
must appear just once).
My issue here is that when I run the program, some numbers are repeated several times.
The code is the following:
public static int randomize(int index) {
//This array will hold the 20 numbers.
int[] randomIndex = new int[20];
Random ranNum = new Random();
for (int x = 0; x<20; x++) {
int temp;
//The number is generated randomly and saved in temp.
temp = ranNum.nextInt(20);
//This loop skips the first index.
if (x != 0){
/*Here, the loop is supposed to compare a generated number with
the previous one*/
for (int y = 1; y<=x; y++) {
while(temp == randomIndex[x-y] ) {
/*If the while loop finds that temp variable matches any previous
number it will generate another random number for it until it finds
no matches.*/
temp = ranNum.nextInt(20);
}
}
}
/*Once no match has been found for temp, the number is assigned to an index,
and the loop is executed with a x variable increment.
randomIndex[x] = temp;
}
//Finally the array with the set of random numbers is sent to the main function.
return randomIndex[index];
}
And I got the following output:
19, 19, 5, 16, 6, 2, 18, 1, 15, 1, 5, 19, 11, 4, 18, 0, 5, 18, 10.
So now I have no idea what to do. :C
When you use Random.nextInt(), there's no guarantee that the numbers generated are unique.
You should generate numbers from 1 to 20 first, then shuffle the numbers. Now the question is changed to "How to shuffle the numbers randomly?"
Perhaps you can refer the implementation of JDK Collections.shuffle().
The algorithm for shuffling the numbers are simple:
Pick first element in the array and swap it with a number at random position.
Repeat step 1 until the last element.
You can avoid it by using something like this:
final Random random = new Random();
final HashSet<Integer> integers = new HashSet<>();
while(integers.size() < 20) {
integers.add(random.nextInt(20));
}
System.out.println(integers);
It looks like you're trying to generate your random numbers by rejection -- that is, by comparing each random number with all previously accepted numbers, and re-generating new ones until you find one that is is different from all of them.
As others have mentioned, it would be far more efficient to generate the numbers from 1 to 20, and shuffle them with a random permutation. However, if implemented correctly, your approach should work... eventually.
A random shuffle implementation might look something like this:
for(int i=0; i<20; i++) { // index goes from 0..19
randomIndex[i] = i + 1; // value goes from 1..20
}
for(int i=0; i<20; i++) {
int j = i + ranNum.nextInt(20 - i); // choose random j from i <= j < 20
int temp = randomIndex[i]; // swap elements i and j
randomIndex[i] = randimIndex[j];
randomIndex[j] = temp;
}
The are two reasons why your posted code generates duplicates. First, when you reject a candidate random number and re-generate a new one, you need to compare it against all existing numbers, restarting you inner (y) loop from the beginning. Your existing code doesn't do that.
Second, I believe that the new Random() constructor generates a different seed each time it is called. If so, your randomize() function is generating a completely different random list each time, and returning the selected index from it. In any case, it makes more sense to return the entire array, instead.
I edited your function for generate array from 1 to 20:
public static int[] randomize() {
int[] randomIndex = new int[20];
Random ranNum = new Random();
boolean isAlreadyIn;
boolean isZero;
int x = 0;
while (x < 20) {
isAlreadyIn = false;
isZero = false;
int temp;
temp = ranNum.nextInt(21);
for(int i = 0; i < randomIndex.length; i++){
if(temp == 0)
isZero = true;
if(temp == randomIndex[i])
isAlreadyIn = true;
}
if (!isZero && !isAlreadyIn){
randomIndex[x] = temp;
x++;
}
}
return randomIndex;
}
hope it will be helpful.