Majority elements in an array (n/3) - java

The code below for the majority elements in an array works for n/2 times of elements, but not for n/3 times. Can anyone help me?
class Solution {
public List<Integer> majorityElement(int[] a) {
ArrayList<Integer> arr = new ArrayList<>();
int flag=0;
for (int i = 0; i < a.length; i++) {
int count = 0;
for (int j = i; j < a.length; j++) {
if (a[i] == a[j])
count++;
}
if (count > a.length/3) {
arr.add(a[i]);
flag=1;
}
}
if (flag==0)
return new ArrayList<>();
return arr;
}
}

You need to traverse from i=0 to n and j=0 to n inorder to calculate frequency of each element, also it would be better if you use a HashMap to solve it, time complexity right now is O(n2), by using hashmap you can solve it in O(n)
https://www.geeksforgeeks.org/majority-element/

You are missing all those elements which are at index lower than i in the second for loop. To count the frequency of a number you need to equate it with all the elements present in the array, even to itself as well if you start with count = 0.
Here is the modified version:
ArrayList<Integer> arr = new ArrayList<>();
for (int i = 0; i < a.length; i++)
{
int count = 0;
for (int j = 0; j < a.length; j++)
if (a[i] == a[j])
count++;
if (count > a.length/3)
arr.add(a[i]);
}
return arr;

Related

Will this code be considered bubble or selection sort?

Could you please help identify what sorting method is this?
public static int[] sort(int arr[]) {
int temp1 = 0;
for (int i = 0; i < arr.length; i++) {
System.out.println(Arrays.toString(arr));
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[i]) {
temp1 = arr[i];
arr[i] = arr[j];
arr[j] = temp1;
}
}
}
return arr;
}
Neither. It is close to selection sort, but makes unnecessary swaps.
Bubble sort makes pair-wise swaps on subsequent elements, until the "lightest" element is at top, like a bubble goes up in fluid.
int unorderedLen = arr.length;
do {
int newUnorderedLen = 0;
// after a cycle, largest element will be at top
for (int i = 1; i < unorderedLen; j++) {
if (arr[i-1] > arr[i]) {
newUnorderedLen = i;
swap(arr, i, i-1);
}
}
unorderedLen = newUnorderedLen;
} while (unorderedLen > 0);
Selection sort searches and selects the place where an element should fit and makes a single swap after.
// at i. cycle, we select i. least element and place at i.
for (int i = 0; i < arr.length-1; i++) {
int minIndex = i;
// search for least element in the remaining unsorted
for (int j = i+1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
if (minIndex != i) {
swap(arr, minIndex, i);
}
}

Java sorting algorithm problems

I need to make a programm in java with the selection sort algorithm. So i tried this to do that but the code doesn't works.
Problem with this code is that it doesn't swap numbers. Instead, it replaces array[i] with the minimum number found. You can modify your loop like this to do the swapping.
for (int i = 0; i < array.length; i++) {
int minIndex = i;
for (int j = i; j < array.length; j++) {
if (array[j] < array[minIndex]) {
minIndex = j;
}
}
if (array[minIndex] != array[i]) {
int wert = array[minIndex];
array[minIndex] = array[i];
array[i] = wert;
}
}
For selection sort use this method
public static void selectionSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int index = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[index]) {
index = j;//searching for lowest index
}
}
int smallerNumber = arr[index];
arr[index] = arr[i];
arr[i] = smallerNumber;
}
}
If you need an ascend order just use:
Arrays.sort(array) from java.util library
But if you need to sort descending I'd suggested to reffer to:
https://www.baeldung.com/java-sorting-arrays

What is wrong in my bubble sort using ArrayList?

What is wrong in my bubble sort in ArrayList? It was not sorted . I am a beginner.
public static ArrayList < Integer > bubbleSort(ArrayList < Integer > ar) {
for (int i = 0; i < ar.size() - 1; i++) {
int indexMax = i;
for (int j = 1; j < ar.size(); j++) {
if (ar.get(indexMax) > ar.get(j)) {
indexMax = j;
}
}
if (indexMax != i) {
int temp = ar.get(i);
ar.set(i, ar.get(indexMax));
ar.set(indexMax, temp);
}
}
return ar;
}
Are you sure you should start from 2nd element (j=1) every time?
Try j=i. i.e.,
public static ArrayList<Integer> bubbleSort (ArrayList<Integer> ar) {
for (int i = 0; i < ar.size() - 1; i++) {
int indexMax = i;
for (int j = i; j < ar.size(); j++) {
if (ar.get(indexMax) > ar.get(j)) {
indexMax = j;
}
}
if (indexMax != i) {
int temp = ar.get(i);
ar.set(i, ar.get(indexMax));
ar.set(indexMax, temp);
}
}
return ar;
}
P.S this will sort your array in ascending order.
Your swapping code block looked like it was outside of loop, so the only one swap occurred for one iteration of main loop.
You are also doing unnecessary comparing of elements, starting your inner loop with precondition j = 1. You should start it from i, as after some iterations of outer loop range from 0 to i will be already sorted.
I think you can use a simpler approach.
for (int i = 0; i < ar.size() - 1; i++) {
for (int j = i; j < ar.size(); j++) {
if (ar.get(j) < ar.get(i)) {
Integer temp = ar.get(j);
ar.set(j, ar.get(i));
ar.set(i, temp);
}
}
}
As you can see, swapping takes place inside of the inner loop, and it also skips already sorted part of collection.
You can do sorting like this:
for(int out=inputArray.size()-1; out>0; out--){
for(int j=1; j<=out; j++){
if(inputArray[j-1]<inputArray[j]){
//Swap the elements
int temp = inputArray[j];
inputArray[j]=inputArray[j-1];
inputArray[j-1]=temp;
}
}
}
return inputArray;
Can you try that?
int n = arr.length;
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
{
// swap arr[j+1] and arr[i]
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}

Java array/inverse novice

I'm a novice at java language, and I had a problem that I have to solve, I'm fairly sure that I've done it right yet the tester still crashes.
a brief summary of what if has to do is " Inside an array a, an inversion is a pair of positions i and j inside the array that satisfy simultaneously both i < j and a[i] > a[j]. In combinatorics, the inversion count inside an array is a rough measure how "out of order" that array is. If an array is sorted in ascending order, it has zero inversions, whereas an n-element array sorted in reverse order has n(n-1)/2 inversions, the largest number possible. This method should count the inversions inside the given array arr, and return that count "
here's what I've done/tried
import java.util.Arrays;
public class P2J1
{
public static int countInversions(int[] arr)
{
int inversions = 0;
for (int i = 0; i <= arr.length; i++){
for (int j = i+1; j < i; j++){
if (arr[i] > arr[j]){
inversions++;
}
}
}
return inversions;
}
}
/// here's the tester
#Test public void testCountInversions() {
Random rng = new Random(SEED);
CRC32 check = new CRC32();
for(int i = 0; i < 1000; i++) {
int[] a = new int[i];
for(int j = 0; j < i; j++) {
a[j] = rng.nextInt(100000);
}
check.update(P2J1.countInversions(a));
}
assertEquals(1579619806L, check.getValue());
}
In Java, the array indexing is from 0 to arr.length - 1, you need to change i <= arr.length in your code to i < arr.length. Otherwise you would get ArrayIndexOutofBoundsException
Also #khelwood's suggestion is true. Change (int j = i+1; j < i; j++) to (int j = i+1; j < arr.length; j++)

Java Array of unique randomly generated integers

public static int[] uniqueRandomElements (int size) {
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[j] = (int)(Math.random()*10);
}
}
}
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
return a;
}
I have a method above which should generate an array of random elements that the user specifies. The randomly generated integers should be between 0 and 10 inclusive. I am able to generate random integers but the problem I have is checking for uniqueness. My attempt to check for uniqueness is in my code above but the array still contains duplicates of integers. What am I doing wrong and could someone give me a hint?
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[j] = (int)(Math.random()*10); //What's this! Another random number!
}
}
}
You do find the duplicate values. However, you replace it with another random number that may be a duplicate. Instead, try this:
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);//note, this generates numbers from [0,9]
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
i--; //if a[i] is a duplicate of a[j], then run the outer loop on i again
break;
}
}
}
However, this method is inefficient. I recommend making a list of numbers, then randomizing it:
ArrayList<Integer> a = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){ //to generate from 0-10 inclusive.
//For 0-9 inclusive, remove the = on the <=
a.add(i);
}
Collections.shuffle(a);
a = a.sublist(0,4);
//turn into array
Or you could do this:
ArrayList<Integer> list = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){
list.add(i);
}
int[] a = new int[size];
for (int count = 0; count < size; count++){
a[count] = list.remove((int)(Math.random() * list.size()));
}
It might work out faster to start with a sequential array and shuffle it. Then they will all be unique by definition.
Take a look at Random shuffling of an array, and at the Collections.shuffle function.
int [] arr = [1,2,3,.....(size)]; //this is pseudo code
Collections.shuffle(arr);// you probably need to convert it to list first
If you have a duplicate you only regenerate the corresponding number once. But it might create another duplicate. You duplicate checking code should be enclosed in a loop:
while (true) {
boolean need_to_break = true;
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
need_to_break = false; // we might get another conflict
a[j] = (int)(Math.random()*10);
}
}
if (need_to_break) break;
}
But make sure that size is less than 10, otherwise you will get an infinite loop.
Edit: while the above method solves the problem, it is not efficient and should not be used for large sized arrays. Also, this doesn't have a guaranteed upper bound on the number of iterations needed to finish.
A better solution (which unfortunately only solves second point) might be to generate a sequence of the distinct numbers you want to generate (the 10 numbers), randomly permute this sequence and then select only the first size elements of that sequence and copy them to your array. You'll trade some space for a guarantee on the time bounds.
int max_number = 10;
int[] all_numbers = new int[max_number];
for (int i = 0; i < max_number; i++)
all_numbers[i] = i;
/* randomly permute the sequence */
for (int i = max_number - 1; i >= 0; i--) {
int j = (int)(Math.random() * i); /* pick a random number up to i */
/* interchange the last element with the picked-up index */
int tmp = all_numbers[j];
all_numbers[j] = a[i];
all_numbers[i] = tmp;
}
/* get the a array */
for (int i = 0; i < size; i++)
a[i] = all_numbers[i];
Or, you can create an ArrayList with the same numbers and instead of the middle loop you can call Collections.shuffle() on it. Then you'd still need the third loop to get elements into a.
If you just don't want to pay for the added overhead to ArrayList, you can just use an array and use Knuth shuffle:
public Integer[] generateUnsortedIntegerArray(int numElements){
// Generate an array of integers
Integer[] randomInts = new Integer[numElements];
for(int i = 0; i < numElements; ++i){
randomInts[i] = i;
}
// Do the Knuth shuffle
for(int i = 0; i < numElements; ++i){
int randomIndex = (int)Math.floor(Math.random() * (i + 1));
Integer temp = randomInts[i];
randomInts[i] = randomInts[randomIndex];
randomInts[randomIndex] = temp;
}
return randomInts;
}
The above code produces numElements consecutive integers, without duplication in a uniformly random shuffled order.
import java.util.Scanner;
class Unique
{
public static void main(String[]args)
{
int i,j;
Scanner in=new Scanner(System.in);
int[] a=new int[10];
System.out.println("Here's a unique no.!!!!!!");
for(i=0;i<10;i++)
{
a[i]=(int)(Math.random()*10);
for(j=0;j<i;j++)
{
if(a[i]==a[j])
{
i--;
}
}
}
for(i=0;i<10;i++)
{
System.out.print(a[i]);
}
}
}
Input your size and get list of random unique numbers using Collections.
public static ArrayList<Integer> noRepeatShuffleList(int size) {
ArrayList<Integer> arr = new ArrayList<>();
for (int i = 0; i < size; i++) {
arr.add(i);
}
Collections.shuffle(arr);
return arr;
}
Elaborating Karthik's answer.
int[] a = new int[20];
for (int i = 0; i < size; i++) {
a[i] = (int) (Math.random() * 20);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[i] = (int) (Math.random() * 20); //What's this! Another random number!
i--;
break;
}
}
}
int[] a = new int [size];
for (int i = 0; i < size; i++)
{
a[i] = (int)(Math.random()*16); //numbers from 0-15
for (int j = 0; j < i; j++)
{
//Instead of the if, while verifies that all the elements are different with the help of j=0
while (a[i] == a[j])
{
a[i] = (int)(Math.random()*16); //numbers from 0-15
j=0;
}
}
}
for (int i = 0; i < a.length; i++)
{
System.out.println(i + ". " + a[i]);
}
//Initialize array with 9 elements
int [] myArr = new int [9];
//Creating new ArrayList of size 9
//and fill it with number from 1 to 9
ArrayList<Integer> myArrayList = new ArrayList<>(9);
for (int i = 0; i < 9; i++) {
myArrayList.add(i + 1);
}
//Using Collections, I shuffle my arrayList
Collections.shuffle(myArrayList);
//With for loop and method get() of ArrayList
//I fill my array
for(int i = 0; i < myArrayList.size(); i++){
myArr[i] = myArrayList.get(i);
}
//printing out my array
for(int i = 0; i < myArr.length; i++){
System.out.print(myArr[i] + " ");
}
You can try this solution:
public static int[] uniqueRandomElements(int size) {
List<Integer> numbers = IntStream.rangeClosed(0, size).boxed().collect(Collectors.toList());
return Collections.shuffle(numbers);
}

Categories

Resources