Related
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 1 year ago.
Improve this question
I'm working on a problem that says "Given an array of N items, take the item from the first position and arrange the array such that the item in its final ordered position and all of the items <= to that item come before it and all of the items >= come after it. The list is not sorted. Only one item is in its final order." What I am trying to do is sort an array so the I get the elements that are smaller than or equal to the element at array[0] to be in the array first then a[0], and at the end of the array should the elements that are greater than or equal to array[0]. For Example, if I have an array of 10 numbers like this "[3, 2, 8, 1, 9, 5, 1, 9, 5, 9]" My new array should be "[2, 1, 1, 3, 8, 9, 5, 9, 5, 9]". I've tried writing the code below but it doesn't work as it should. The output I get is instead [3, 5, 1, 2, 9, 9, 1, 9, 8, 5]. Can someone help me figure out how to fix this?
import java.util.Arrays;
import java.util.Random;
public class Q1 {
public static void main(String[] args) {
int[] d = createRandomIntArray(10);
System.out.println("Original Array: " + Arrays.toString(d));
changeOrder(d);
System.out.println("New Array: " + Arrays.toString(d));
}
public static int[] createRandomIntArray(int n) {
Random random = new Random();
int[] result = new int[n];
for (int i = 0; i < n; i++)
result[i] = random.nextInt(n);
return result;
}
public static void swap(int[] x, int i, int j) {
int temp = x[i];
x[i] = x[j];
x[j] = temp;
}
public static void changeOrder(int[] array) {
int count = 0;
for (int i = 0; i < array.length - 1; i++) {
if (array[0] <= array[i + 1]) {
swap(array, array[0], array[count++]);
} else if (array[0] >= array[i + 1]) {
swap(array, array[i + 1], array[array.length - 1]);
}
}
}
}
It seems that the algorithm should be reconsidered just to move the lower elements before the head element starting at position 0:
if current element is less than head, rotate all elements from head to current position to the right by 1.
Example implementation:
static void arrange(int[] arr) {
int head = 0;
for (int i = head + 1; i < arr.length; i++) {
if (arr[i] < arr[head]) {
rotate(arr, head, i);
head++;
}
}
}
static void rotate(int[] arr, int head, int i) {
int tmp = arr[i];
for (int j = i; j > head; j--) {
arr[j] = arr[j - 1];
}
arr[head] = tmp;
}
Test:
int[] arr = {3, 2, 8, 1, 9, 5, 1, 9, 5, 9};
System.out.println("before: " + Arrays.toString(arr));
arrange(arr);
System.out.println("after: " + Arrays.toString(arr));
Output:
before: [3, 2, 8, 1, 9, 5, 1, 9, 5, 9]
after: [2, 1, 1, 3, 8, 9, 5, 9, 5, 9]
int[] arr = {9, 2, 8, 1, 9, 5, 1, 9, 5, 9};
System.out.println("before: " + Arrays.toString(arr));
arrange(arr);
System.out.println("after: " + Arrays.toString(arr));
Output:
before: [9, 2, 8, 1, 9, 5, 1, 9, 5, 9]
after: [2, 8, 1, 5, 1, 5, 9, 9, 9, 9]
This is a simple coding questions that is asking to sum the marks for each students. If the total marks reaches the pass mark then reach to the next student. If they did not reach the pass marks then it will return as failed.
class StudentMarks {
public int getCountFailures() {
int[] student1 = {3, 2, 6, 4, 3, 6, 6, 7, 3, 2};
int[] student2 = {8, 7, 8, 9, 10, 7, 6, 8, 9, 6};
int[] student3 = {2, 5, 3, 1, 4, 3, 3, 2, 5, 6};
int[][] allStudents = {student1, student2, student3};
int numberFails = 0;
int passMark = 50;
// YOUR CODE GOES HERE
return numberFails;
}
}
Test code
int numberFails = marks.getCountFailures();
System.out.println("Number of fails = " + numberFails);
How would I implement a way to sum the marks for each of the students and return the number of fails.
The expected outcome
Number of fails = 2
Seems as a homework question, so this is not a complete answer but would help you come up with one on your own.
// will return the count of the arrays - the sum of the elements
// of which are equal to or cross the threshold.
long count =
Arrays.stream(allStudents)
.peek(a -> System.out.println(Arrays.toString(a)))
.filter(a -> thresholdSum(a) )
.count();
System.out.print(count);
This is the helper method.
public static boolean thresholdSum(int[] a) {
int threshold = 50;
int sum =0;
for (int i : a) {
sum += i;
if (sum >= threshold) {
return true;
}
}
return false;
}
So I came across this problem in Java that wants to remove a list of number that has occurred more than twice but keeping the order, and the first two occurrences.
For example, if the list is 2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10
the expected output would be 2, 3, 5, 4, 5, 2, 4, 3, 10
I've tried several methods, including using a counter int to keep track of the occurrences and filter it out, but I am not sure how I can go about it
class DeDup {
// function to find the element occurring more than 3 times
static void get2Occurrences(int arr[]) {
int i;
int count = 0;
for (i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
if (arr[i] == arr[j])
count++;
}
if (count < 3 && count > 0) {
//return arr[i];
System.out.print(arr[i] + ", ");
} else {
for (int k = 2; k > 0; k--) {
System.out.print(arr[i] + ", ");
}
}
}
}
// driver code
public static void main(String[]args) {
int arr[] = new int[]{ 2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10 };
//expected output: 2, 3, 5, 4, 5, 2, 4, 3, 10
//int n = arr.length;
get2Occurrences(arr);
}
}
the expected output would be 2, 3, 5, 4, 5, 2, 4, 3, 10
but i got 2, 2, 3, 3, 5, 5, 4, 4, 5, 5, 2, 2, 4, 4, 3, 3, 5, 5, 2, 2, 4, 4, 4, 4, 2, 2, 10, 10,
I would do it using a pair of Sets: Set.add returns a boolean indicating whether the element was added. Hence:
boolean b = set1.add(num) || set2.add(num);
will be true if it was added into either set - and it will only try to add it to set2 if it was already in set1 - and false otherwise, meaning it was present in both sets already.
Set<Integer> set1 = new HashSet<>();
Set<Integer> set2 = new HashSet<>();
for (Integer a : arr) {
if (set1.add(a) || set2.add(a)) {
System.out.print(a + ", ");
}
}
Ideone demo
Keep track of the number of occurrences found for each element.
Something like this:
static void get2Occurrences(int arr[])
{
// Initialize occurrences found
Hashtable<Integer, Integer> found_elms = new Hashtable<Integer, Integer>();
// Loop over all elements
int counter;
int number;
Integer found;
for (counter = 0; counter < arr.length; counter++)
{
number = arr[counter];
found = found_elms.get(number);
if (found == null)
found = 1;
else
found = found + 1;
found_elms.put(number, found);
if (found < 3)
System.out.print(number + ", ");
}
System.out.println();
} // get2Occurrences
In this solution, you can change the number of repetitions from three to another.
int[] arr = new int[]{2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10};
Map<Integer, Integer> counting = new HashMap<>();
for (Integer current : arr) {
int count = counting.compute(current, (x, n) -> n == null ? 1 : n + 1);
if (count < 3) {
System.out.print(current + ", ");
}
}
I would propose an insert filter : go through each element with a for loop and insert it into a response array if the response arrays doesnt contain it 2 times yet
import java.util.ArrayList;
import java.util.List;
...
List<Integer> lst = new ArrayList<>();
for (int i : arr) {
if (lst.lastIndexOf(i) == lst.indexOf(i)) {
lst.add(i);
}
}
return lst.stream().mapToInt(i -> i).toArray();
So this is what I came up with in the end
import java.util.ArrayList;
import java.util.Arrays;
class DeDup {
// function to find the element occurring more than 3 times
static void get2Occurrences(ArrayList<Integer> arr)
{
for(int i=0; i<arr.size(); i++){
int count=0;
for(int j=0; j<i; j++){
if(arr.get(j)==arr.get(i)){
count++;
}
}
if (count>=2){
arr.remove(i);
i--;
}
}
System.out.println("Output: "+arr);;
}
// driver code
public static void main(String[] args)
{
ArrayList<Integer> arr = new ArrayList<Integer>(Arrays.asList( 2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10));
//expected output: 2, 3, 5, 4, 5, 2, 4, 3, 10
//int n = arr.length;
System.out.println("Input: "+arr);
get2Occurrences(arr);
}
}
Solution using Iteartor:
List<Integer> array = Lists.newArrayList(2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2, 10);
Map<Integer, Integer> control = new HashMap<>();
Iterator<Integer> iterator = array.iterator();
while(iterator.hasNext()) {
Integer element = iterator.next();
Integer occurrences = control.getOrDefault(element, 0);
if (occurrences >= 2) {
iterator.remove();
} else {
control.put(element, occurrences + 1);
}
}
I'm trying to solve a problem on CodeFights called firstDuplicate, that states -
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.
My solution -
public class FirstDuplicate {
private static HashMap<Integer, Integer> counts = new HashMap<>();
private static void findSecondIndexFrom(int[] num, int n, int i) {
// given an array, a starting index and a number, find second occurrence of that number beginning from next index
for(int x = i; x < num.length; x++) {
if(num[x] == n) {
// second occurrence found - place in map and terminate
counts.put(n, x);
return;
}
}
}
private static int firstDuplicate(int[] a) {
// for each element in loop, if it's not already in hashmap
// find it's second occurrence in array and place number and index in map
for(int i = 0; i < a.length; i++) {
if(!counts.containsKey(a[i])) {
findSecondIndexFrom(a, a[i], i+1);
}
}
System.out.println(counts);
// if map is empty - no duplicate elements, return -1
if(counts.size() == 0) {
return -1;
}
// else - get array of values from map, sort it, find lowest value and return corresponding key
ArrayList<Integer> values = new ArrayList<>(counts.values());
Collections.sort(values);
int lowest = values.get(0);
//System.out.println(lowest);
for(Map.Entry<Integer, Integer> entries: counts.entrySet()) {
if(entries.getValue() == lowest) {
return entries.getKey();
}
}
return -1;
}
public static void main(String[] args) {
// int[] a = new int[]{2, 3, 3, 1, 5, 2};
//int[] a = new int[]{2, 4, 3, 5, 1};
//int[] a = new int[]{8, 4, 6, 2, 6, 4, 7, 9, 5, 8};
//int[] a = new int[]{1, 1, 2, 2, 1};
int[] a = new int[]{10, 6, 8, 4, 9, 1, 7, 2, 5, 3};
System.out.println(firstDuplicate(a));
}
}
This solution passes only for about 4 of the 11 test cases on CodeFights. However, I manually executed each one of the test cases in my IDE, and each one produces the right result.
I can't figure out why this won't work in CodeFights. Does it have something to do with the use of the static HashMap?
Edited: Since adding and checking if element is present in Set can be done in one step, code can be simplified to:
public static int findDuplicateWithLowestIndex(int... a){
Set<Integer> set = new HashSet<>();
for(int num : a){
if(!set.add(num)){
return num;
}
}
return -1;
}
You're completly right Patrick.
Use this solution: here duplicateIndex should be very large number.
package sample;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Duplicate {
public static Integer secondIndex(Integer[] arr) {
List<Integer> arrlist = new ArrayList<>(Arrays.asList(arr));
int duplicateIndex = 999;
int ele = 0;
for (int i = 0; i < arrlist.size(); i++) {
int secondIndex = getSecondIndex(arrlist, arrlist.get(i));
if (secondIndex >= 0 && duplicateIndex > secondIndex) {
duplicateIndex = secondIndex;
ele = arrlist.get(i);
}
}
return duplicateIndex == 999 ? -1 : ele;
}
public static int getSecondIndex(List<Integer> arr, int ele) {
List<Integer> var0 = new ArrayList<>(arr);
var0.set(var0.indexOf(ele), -1);
return var0.indexOf(ele);
}
public static void main(String[] str) {
// Integer[] arr = new Integer[] { 2, 3, 3, 1, 5, 2 };
// Integer[] arr = new Integer[] { 2, 4, 3, 5, 1 };
// Integer[] arr = new Integer[] { 8, 4, 6, 2, 6, 4, 7, 9, 5, 8 };
// Integer[] arr = new Integer[]{1, 1, 2, 2, 1};
Integer[] arr = new Integer[] { 10, 6, 8, 4, 9, 1, 7, 2, 5, 3 };
System.out.println(secondIndex(arr));
}
}
Solution in Javascript
function solution(a) {
const duplicates = [];
for (const i of a) {
if (duplicates.includes(i))
return i;
else
duplicates.push(i);
}
return -1;
}
console.log(solution([2, 1, 3, 5, 3, 2])); // 3
console.log(solution([2, 2])); // 2
console.log(solution([2, 4, 3, 5, 1])); // -1
I have to re write my implementation vor insert/selection-sort in Java from PHP. So, the algorithms work fine but as it's a pain in the rear to work with all the different types when writing a quick programm I'm using a Logger Class in order to save my multi-type values.
As I haven't worked with Java for a while, there might be a problem in the code that causes this weird bug.
I have to iterate over an Integer Array in order to generate and sort random Arrays of different lengths:
public static Log[][] eval(Integer[] sizes, Algorithm alg){
Log[][] logs = new Log[sizes.length][2];
for (int i = 0; i < sizes.length; i++) {
Log[] tmp = new Log[3];
Integer[] rand = randomArray(sizes[i]);
System.out.println("Before "+Arrays.toString(rand));
tmp[0] = new Log(sizes[i], rand);
tmp[1] = alg.insertionSort(rand);
tmp[2] = alg.selectionSort(rand);
System.out.println("After "+Arrays.toString(rand));
logs[i] = tmp;
}
return logs;
}
As you see, there are 2 debugs, which will give something like this:
Before [2, 1, 4, 5, 3]
After [1, 2, 3, 4, 5]
Before [1, 8, 9, 10, 5, 4, 2, 6, 7, 3]
After [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Before [11, 15, 20, 16, 18, 8, 4, 13, 2, 19, 12, 3, 10, 5, 17, 14, 1,
9, 6, 7]
After [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20]
This is strange, as I doesnt change the rand value. Even if I put an Int array called backup outside the loop and overwrite it and print out this in the last log, it's still a sorted array. I'm trying to fix this for over a hour and I can't find the bug. It must be within the algorithm methodes for index 1/2, because Before == After when skipping these lines. But I have no clue, what's wrong, as I'm only using the array as parameter and return an Object of Log.
Here's one algorithm-method:
public Log insertionSort(Integer[] sortieren) {
double startTime = System.nanoTime();
int temp;
for (int i = 1; i < sortieren.length; i++) {
temp = sortieren[i];
int j = i;
while (j > 0 && sortieren[j - 1] > temp) {
sortieren[j] = sortieren[j - 1];
j--;
}
sortieren[j] = temp;
}
double stopTime = System.nanoTime();
double time = stopTime - startTime;
Log log = new Log("Insertion-Sort", (time/1000000), sortieren);
return log;
}
And this is my Log Class:
public class Log {
public String name;
public double time;
public int size;
public Integer[] sorted;
public Integer[] randArray;
public Log(String name, double time, Integer[] sorted){
this.name = name;
this.time = time;
this.sorted = sorted;
}
public Log(int size, Integer[] random){
this.size = size;
this.randArray = random;
}
}
Later, I want to evalue this through this method:
public static void reportLogger(Log[][] log, boolean showArray){
for (int i = 0; i < log.length; i++) {
// Show Initial Array (0th Index) -> (size, array)
for (int j = 1; j <= 2 ; j++) {
Log tmp = log[i][j];
// 1st/2nd Index -> Insert/Selection -> name, time, sortedArray by using tmp.name ,etc..
System.out.println("---------------------");*/
}
}
The array is an input parameter, but it is also modified in the first sorting method alg.insertionSort(rand). At this point, the array became a sorted array - no longer a random one. At the point alg.selectionSort(rand), all it's trying to do is sorting on a sorted array rand. In order to compare the performance, you should make a copy of the array rand:
tmp[0] = new Log(sizes[i], rand);
Integer[] array_copy_1 = Array.copyof(rand, rand.size)
tmp[1] = alg.insertionSort(array_copy_1);
Integer[] array_copy_2 = Array.copyof(rand, rand.size)
tmp[2] = alg.selectionSort(array_copy_2);