ways to speed up the Full Counting Sort - java

I encountered a question on hackerrank.
https://www.hackerrank.com/challenges/countingsort4
My first attempt passed all the test cases except the last one, due to timeout.
After failed to come up with a more efficient algorithm, I improved the code by using StringBuilder instead of concatenating Strings directly. This brought the running time from more than 5 sec to 3.5 sec.
My question is that is there any other way that I can improve the running time?
Thanks.
The following is my code.
public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
scanner.nextLine();
int[] oriNum = new int[N];
String[] oriStr = new String[N];
int[] count = new int[100];
int[] indices = new int[100];
int[] output = new int[N];
// save the originals and the count array
for (int i = 0; i < N; i++) {
oriNum[i] = scanner.nextInt();
oriStr[i] = scanner.nextLine().trim();
count[oriNum[i]]++;
}
// accumulate the count array
indices[0] = 0;
for (int i = 1; i < 100; i++) {
indices[i] = indices[i-1] + count[i-1];
}
// output order
for (int i = 0; i < N; i++) {
int num = oriNum[i];
output[indices[num]++] = i;
}
int bar = N/2;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < N; i++) {
int index = output[i];
if (index < bar)
sb.append("- ");
else
sb.append(oriStr[index]+ " ");
}
System.out.println(sb.toString());
}
}

You should try a plain buffered reader instead of Scanner. Scanner is surprisingly slow and I have participated in programming competitions where Scanner was the sole reason for "time limit exceeded".

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution
{
public static void main(String[] args)throws Exception
{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(in.readLine());
int[] c=new int[100];
String[][] dt=new String[100][10300];
for(int i=0;i<n;i++)
{
String[] str=in.readLine().split(" ");
int val=Integer.parseInt(str[0]);
if(i<n/2)
dt[val][c[val]]="-";
else
dt[val][c[val]]=str[1];
c[val]++;
}
StringBuilder sb=new StringBuilder("");
for(int i=0;i<100;i++)
if(i<n)
for(int k=0;k<c[i];k++)
if(dt[i][k]!=null)
sb.append(dt[i][k]+" ");
else break;
System.out.println(sb.toString());
}
}

This was my approach to problem. (it is in c++).
void counting_sort(vector<int> &arr, int size, vector<vector<string> > foo, vector<int> first_half)
{
int max = *max_element(arr.begin(), arr.end());
int min = *min_element(arr.begin(), arr.end());
int range = max - min + 1;
int count[range] = {0};
// counting frequency of numbers in array
for (int i = 0; i < size; i++)
{
count[arr[i] - min]++;
}
// calculating cumulative sum
for (int i = 1; i < range; i++)
{
count[i] += count[i - 1];
}
vector<vector<string> > output(size);
// making the new sorted array
for (int i = size - 1; i >= 0; i--) // traversing from backward for stability
{
output[count[arr[i]-min] - 1] = foo[i];
count[arr[i]-min]--;
}
// copying the sorted array in original array
int j=0;
for (int i = 0; i < size; i++)
{
if(stoi(output[i][0]) == first_half[j])
{
cout << "- ";
j++;
}
else
{
cout << output[i][1] << ' ';
}
}
}
// Complete the countSort function below.
void countSort(vector<vector<string>> arr) {
vector<int> num;
vector<int> first_half;
for(int i=0; (unsigned)i<arr.size(); i++)
{
num.push_back(stoi(arr[i][0]));
if(i < ((unsigned)arr.size()/2))
{
first_half.push_back(stoi(arr[i][0]));
}
}
sort(first_half.begin(), first_half.end());
counting_sort(num, num.size(), arr, first_half);
}

Related

Worst fit algorithm Java

I'm working on a worst fit algorithm in Java using a dynamic array , I'm trying to add and delete blocks/processes , the addition is working perfectly fine but when I want to delete a block , I'm not really sure if it's deleting the blocks well or no , I had an error message that said : Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3.I fixed the code and it's working , could someone please tell me if i'm doing it corrct or no
Here's the CODE :
import java.util.Arrays;
import java.util.Scanner;
public class GFG {
// Method to allocate memory to blocks as per worst fit
// algorithm
static int[] worstFit(int[] blockSize, int[] processSize) {
// Stores block id of the block allocated to a
// process
int m = blockSize.length;
int n = processSize.length;
int[] allocation = new int[n];
// Initially no block is assigned to any process
Arrays.fill(allocation, -1);
// pick each process and find suitable blocks
// according to its size ad assign to it
for (int i = 0; i < n; i++) {
// Find the best fit block for current process
int wstIdx = -1;
for (int j = 0; j < m; j++) {
if (blockSize[j] >= processSize[i]) {
if (wstIdx == -1)
wstIdx = j;
else if (blockSize[wstIdx] < blockSize[j])
wstIdx = j;
}
}
// If we could find a block for current process
if (wstIdx != -1) {
// allocate block j to p[i] process
allocation[i] = wstIdx;
// Reduce available memory in this block.
blockSize[wstIdx] -= processSize[i];
}
}
System.out.println("\nProcess No.\tProcess Size\tBlock no.");
for (int i = 0; i < n; i++) {
System.out.print(" " + (i + 1) + "\t\t" + processSize[i] + "\t\t");
if (allocation[i] != -1)
System.out.print(allocation[i] + 1);
else
System.out.print("Not Allocated");
System.out.println();
}
return allocation;
}
static Scanner in = new Scanner(System.in);
// Driver Method
public static void main(String[] args) {
int[] blockSize = addBlocks();
int[] processSize = addProcess();
int[] allocation = worstFit(blockSize, processSize);
int[] temp = deleteBlock(blockSize);
worstFit(temp, processSize);
}
private static int[] addBlocks() {
int[] temp = null;
System.out.print("Enter number of blocks : ");
int len = in.nextInt();
temp = new int[len];
for (int i = 0; i < len; i++) {
System.out.printf("Enter block[%s] size: ", i);
temp[i] = in.nextInt();
}
return temp;
}
private static int[] deleteBlock(int[] blocks) {
int c = 0;
for (int i = 0; i < blocks.length; i++) {
System.out.printf("Block id %s blockSize= %s%n", i, blocks[i]);
}
System.out.println("Enter block id to delete");
int id = in.nextInt();
int[] temp = new int[blocks.length - 1];
if (id == blocks.length) {
for (int i = 0; i < temp.length; i++) {
temp[i] = blocks[i];
}
}
else if(id<blocks.length)
for (int i = 0; i < temp.length; i++){
if(i!=id){
temp[c] = blocks[i];
c++;
}
}
return temp;
}
private static int[] addProcess() {
int[] temp;
System.out.print("Enter number of Process : ");
int len = in.nextInt();
temp = new int[len];
for (int i = 0; i < len; i++) {
System.out.printf("Enter Process[%s] size: ", i);
temp[i] = in.nextInt();
}
return temp;
}
private static void deleteProcess() {
}
}

Storing output of a nested loop as new array - Java

I need to find the largest prime number of a given array when adding two numbers in an array,so I decided to add all possible sums first and displayed it. Now I want to take those output elements to a new array.Please help me solve this problem.
import java.util.Scanner;
public class main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int noOfElem = scanner.nextInt();
int[] array = new int[noOfElem];
int[][] newArray = new int[5][4];
int i=0;
while(scanner.hasNextInt()){
array[i] = scanner.nextInt();
i++;
if(i == noOfElem){
break;
}
}
for (int a = 0; a < array.length; a++)
{
for (int b = a+1; b < array.length; b++) {
int m = array[a] + array[b];
newArray[a][b] =
}
}
}
}
Not quite sure what the problem is here, just do
newArray[a][b] = m;
This stores all sums of all 'a's and 'b's such that newArray[a][b] is the sum of array[a] + array[b]

How stop array input limit then the result to show the output?

I have a question about stop array input limit then the result to show the output.
Below is my coding have already set new float[3][3]:
import java.util.Scanner;
public class Clone2Darray {
public static float[][] clone(float[][] a) throws Exception {
float b[][] = new float[a.length][a[0].length];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
b[i][j] = a[i][j];
}
}
return b;
}
public static void main(String args[]) {
Scanner sc = new Scanner (System.in);
System.out.println ("Type nine float numbers two-dimensional array of similar type and size with line breaks, end by -1:");
float[][] a = new float[3][3];
for (int i=0; i<3; i++){
for (int j=0; j<3; j++){
String line = sc.nextLine();
if ("-1".equals(line)){
break;
}
a[i][j]=Float.parseFloat(line);
}
}
System.out.println("\n The result is:");
try {
float b[][] = clone(a);
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
System.out.print(b[i][j] + " ");
}
System.out.println();
}
} catch (Exception e) {
System.out.println("Error!!!");
}
}
}
The limit output is show me like below:
run:
Type float numbers in the two-dimensional array of similar type and size
with line breaks, end by -1:
5.33
9.33
63.33
6.36
3.55
7.25
2.33
3.66
The result is:
6.33 5.33 9.33
63.33 6.36 3.55
7.25 2.33 3.66
BUILD SUCCESSFUL (total time: 31 seconds)
My problem is want to stop limit float[3][3] and can unlimited key in the input until type -1 to stop the input. May I know how to remove the limit float[3][3] in the array? Hope anyone can guide me to solve my problem. Thanks.
At the point when you allocate memory for the two-dimensional array you have to tell the sizes of its elements, because memory will be allocated for that array and the amount of memory to be allocated must be known.
You can bypass this, by using some more dynamic types, like List and its popuplar implementation, ArrayList, even in a nested form. That's a nice thing to do, but then you will not have a "real" array.
The below code allows you to create the dynamic arrays.
import java.util.Scanner;
public class Clone2DArray {
public static float[][] clone(float[][] a) throws Exception {
float b[][] = new float[a.length][a[0].length];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
b[i][j] = a[i][j];
}
}
return b;
}
public static void main(String args[]) {
Scanner sc = new Scanner (System.in);
System.out.println("enter row size");
int row = Integer.parseInt(sc.nextLine());
System.out.println("enter column size");
int column = Integer.parseInt( sc.nextLine());
System.out.println ("Type float numbers two-dimensional array of similar type and size with line breaks:");
float[][] a = new float[row][column];
for (int i=0; i<row; i++){
for (int j=0; j<column; j++){
String line = sc.nextLine();
if ("-1".equals(line)){
break;
}
a[i][j]=Float.parseFloat(line);
}
}
System.out.println("\n The result is:");
try {
float b[][] = clone(a);
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[0].length; j++) {
System.out.print(b[i][j] + " ");
}
System.out.println();
}
} catch (Exception e) {
System.out.println("Error!!!");
}
}
}

Cut the sticks: Hackerrank warmup challenge

I've been trying to solve the warmup challenges on Hackerrank. For this particular challenge - https://www.hackerrank.com/challenges/cut-the-sticks - I've written some code, and although it seems logically correct to me, I'm not getting the right answer.
My Code -
import java.util.*;
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int lengths[] = new int[n];
List<Integer> output = new LinkedList<Integer>();
for (int i = 0; i < n; i++)
lengths[i] = sc.nextInt();
sc.close();
Arrays.sort(lengths);
for (int i = 0; i < n; i++) {
if (lengths[i] == 0)
continue;
else {
output.add(n - i);
for (int j = i; j < n; j++) { // This loop isn't working like it should
lengths[j] -= lengths[i];
// System.out.print(lengths[j] + " "); // For debugging purposes
}
// System.out.println("");
}
}
for (int i = 0; i < output.size(); i++)
System.out.println(output.get(i));
}
}
For the following input -
6
5 4 4 2 8 2
The output I get is -
6
5
4
3
2
1
The correct output should be -
6
4
2
1
I tried to display the values of the lengths array throughout the runs of the for loop marked in the code (with a comment), and this is what i get for the same inputs as above -
0 2 4 4 5 8
0 4 4 5 8
0 4 5 8
0 5 8
0 8
0
6
5
4
3
2
1
I'm totally stumped as to why this would happen.
The problem is here:
lengths[j] -= lengths[i];
When i == j is true, this changes the value of lengths[i]. You need to save that value first.
final int v = lengths[i];
for (int j = i; j < n; j++) {
lengths[j] -= v;
}
Had solved it sometime back.
Here's a version of answer, using a do while loop
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int size = scan.nextInt();
int sticks [] = new int[size];
for (int i = 0; i < size; i++){
sticks[i] = scan.nextInt();
}
Arrays.sort(sticks);
do {
int count =0;
int leastLength = sticks[0];
for (int j=0; j < sticks.length; j++){
sticks[j] = sticks[j] - leastLength;
count++;
}
System.out.println(count);
List<Integer> resizeArray = new LinkedList<Integer>();
for ( int i=0; i< sticks.length; i++){
if (sticks[i] != 0){
resizeArray.add(sticks[i]);
}
}
int temp[] = new int[resizeArray.size()];
for (int i = 0; i < resizeArray.size(); i ++){
temp[i] = resizeArray.get(i);
}
sticks = temp;
} while (sticks.length > 0);
}
package com.omt.learn.algo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class CutTheSticks2 {
public static void main(String s[]) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
short N = Short.parseShort(br.readLine());
short[] A = new short[N];
N = 0;
for (String str : br.readLine().split(" ")) {
A[N++] = Short.parseShort(str);
}
Arrays.sort(A);
StringBuffer sb = new StringBuffer();
System.out.println(N);
for (int i = 1; i < N; i++) {
if (A[i - 1] != A[i]) {
sb.append((N - i) + "\n");
}
}
// OUTPUT
System.out.print(sb);
}
}
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int arr[] = new int[n];
for(int arr_i=0; arr_i < n; arr_i++){
arr[arr_i] = in.nextInt();
}
int count = 2;
int min=1000;
for(int arr_i=0;count !=1 ; arr_i++){ // read
count = 0;
for(int arr_j=0; arr_j < n; arr_j++)// find min
{ if(min >arr[arr_j] && arr[arr_j]!=0)
min=arr[arr_j];
}
for(int arr_k=0; arr_k < n; arr_k++)// sub
{
if(arr[arr_k]>=min)
{ count++;
arr[arr_k]= arr[arr_k] - min;
}
}
System.out.println(count);
}
}
}
This is a working solution in JavaScript. Took me a while to realize that the sort() in JavaScript performs a string comparison in alphabetical order.
function sortNumbers(a, b) {
return a - b;
}
function cutSticks(arr){
var smallestStick = 0;
arr = arr.sort(sortNumbers);
while(arr.length > 0) {
console.log(arr.length);
smallestStick = arr[0];
var newArray = [];
arr.forEach(function (val) {
var newValue = val - smallestStick;
if (newValue > 0) {
newArray.push(newValue);
}
});
arr = newArray;
}
}
function main() {
var n = parseInt(readLine());
arr = readLine().split(' ');
arr = arr.map(Number);
cutSticks(arr);
}
Hope it helps!
Java Version. Passed all tests, but not sure if is best performance.
static int[] cutTheSticks(int[] arr) {
List<Integer> sticks = Arrays.stream(arr).boxed().collect(toList());
List<Integer> cuts = new ArrayList<>();
while (true) {
int min = sticks.stream().mapToInt(Integer::valueOf).min().getAsInt();
Iterator it2 = sticks.iterator();
int cuted = 0;
List<Integer> temp = new ArrayList<>();
while (it2.hasNext()) {
int v = (int) it2.next();
if (v == min) {
it2.remove();
cuted++;
} else {
int nv = v - min;
it2.remove();
temp.add(nv);
cuted++;
}
}
cuts.add(cuted);
sticks.addAll(temp);
if (sticks.isEmpty()) {
break;
}
}
return cuts.stream().mapToInt(Integer::valueOf).toArray();
}

Java Selection Sort Confusion

I don't understand what is happening in this code. Re-post from before with code included. Can someone please explain what is happening here? I understand conceptually that the list is being re-ordered one item at a time, but I just cant grasp this code.
import java.io*;
public class Example {
public static void main(String[] args) throws IOException {
int age[] = new int[10];
int i, j;
int smallest;
int temp;
String line;
BufferedReader in;
in = new BUfferedReader(new InputStreamReader(System.in));
for(i = 0; i<= 9; i++)
{
System.out.println("Enter an age: ");
line = in.readline();
age[i] = Integer.valueOf(line).intValue();
}
for(i = 0; i<= 9, i++) {
smallest = i;
for(j = 1; j<=9; j++)
{
if(age[j] < age[smallest]) {
smallest = j;
}
}
for (i = 0; i<=9; i++)
{
System.out.println(age[i]);
}
}
}
}
This looks like an implementation of the Bubble Sort. There is a wide wealth of information on the topic of this classic (and inefficient!) algorithm both on The Internet and in books on the subject of fundamental algorithms.
import java.io*;
public class Example {
public static void main(String[] args) throws IOException {
int age[] = new int[10];
int i, j;
int smallest;
int temp;
String line;
BufferedReader in;
in = new BUfferedReader(new InputStreamReader(System.in));
for(i = 0; i<= 9; i++)
{
System.out.println("Enter an age: ");
line = in.readline();
age[i] = Integer.valueOf(line).intValue();
}
for(i = 0; i<= 9, i++) {
smallest = i;
for(j = 1; j<=9; j++)// MISTAKE IS IN THIS LINE; YOU SHOULD START THE VALUE OF J FROM I+1(for(j = i+1; j<=9; j++)))
{
if(age[j] < age[smallest]) {
smallest = j;
}
}
//ALSO AFTER FINDING THE SMALLEST ELEMENT YOU HAVE TO SWAP THE SMALLEST ELEMENT WITH I ELEMENT
/*int temp=age[i];
age[i]=age[smallest];
age[smallest]=temp*/
for (i = 0; i<=9; i++)
{
System.out.println(age[i]);
}
}
}
}

Categories

Resources