Hackerrank (Java) MAXIMUM LENGTH SUBSTRING - timeout error - java

Link to this problem:
https://www.hackerrank.com/contests/takneek/challenges/maximum-length-substring/problem
The code passes the initial test case but then times out when I go to submit on hacker rank for much larger strings. I have a feeling it's the algorithm I'm using for the unique substrings, how do I cut down this time into something efficient?
My code:
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);
LinkedList<Integer> kList = new LinkedList<Integer>();
LinkedList<String> setout = new LinkedList<String>();
LinkedList<String> setLex = new LinkedList<String>();
//Get the original text
String text = in.nextLine();
//Get n from the file
int n = in.nextInt();
//Get the next needed items for comparison and order
for (int i = 0; i < n; i++) {
kList.add(in.nextInt());
}
setout = getAllUniqueSubset(text);
setLex = sortLexographically(setout);
int findMax = findMaximumSub(setLex, kList, 0);
// System.out.println(setLex);
System.out.println(findMax);
}
//Get the unique subset to begin with and return it
public static LinkedList<String> getAllUniqueSubset(String text) {
LinkedList<String> set = new LinkedList<String>();
for (int i = 0; i < text.length(); i++) {
for (int j = 0; j < text.length() - i; j++) {
String elem =text.substring(j, j + (i+1));
if (!set.contains(elem)) {
set.add(elem);
}
}
}
return set;
}
public static LinkedList<String> sortLexographically(LinkedList<String> setout){
for(int i = 0; i < setout.size()-1; ++i) {
for (int j = i + 1; j < setout.size(); ++j) {
if (setout.get(i).compareTo(setout.get(j)) > 0) {
String testLex = setout.get(i);
setout.set(i, setout.get(j));
setout.set(j, testLex);
}
}
}
return setout;
}
public static int findMaximumSub(LinkedList<String> setLex, LinkedList<Integer> kList, int maxCheck){
for (int i = 0; i < kList.size()-1; i++) {
if (maxCheck < setLex.get(kList.get(i)).length()) {
maxCheck = setLex.get(kList.get(i)).length();
}
}
return maxCheck;
}
}

Related

How to I create an adjacency matrix out of this?

try to turn in this information into adjacency matrix but confused on how
import java.util.*;
public class graph {
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
int adjMatrix[][];
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
while(stdin.hasNext()) {
String[] str = stdin.nextLine().split("[\\s,]+");
ArrayList<Integer> inner = new ArrayList<Integer>();
for(int i = 0; i < str.length; i++) {
inner.add(Integer.parseInt(str[i]));
}
list.add(inner);
}
}
}
storing the information in an arraylist of arraylist. help on how to make this an adjacency matrix would be appreciated.
If the data you are extracting from stdin are valid you should be able to construct adjacency matrix like this :
public static void main(String[] args) {
String[] input = "1 2 5 \n3 4 2 \n".split("\n");
int adjMatrix[][];
int max = 0;
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
for(int i=0; i<input.length; i++) {
String[] str = input[i].split("[\\s,]+");
ArrayList<Integer> inner = new ArrayList<Integer>();
for(int j = 0; j < str.length; j++) {
inner.add(Integer.parseInt(str[j]));
}
max = Math.max(Math.max(max, inner.get(0)), inner.get(1));
list.add(inner);
}
int[][] adjacencyMatrix = new int[max+1][max+1];
for(int i=0; i<list.size(); i++) {
int source = list.get(i).get(0);
int dest = list.get(i).get(1);
adjacencyMatrix[source][dest] += 1;
}
for(int i=0; i<adjacencyMatrix.length; i++) {
for(int j=0; j<adjacencyMatrix[i].length; j++) {
System.out.print(adjacencyMatrix[i][j]);
}
System.out.println("");
}
}
I did not take the weight in account since it does not seems to be revelant for adjacency matrix
public static void main(String[] args) {
Scanner stdin = new Scanner(System.in);
int nodeCount = 0;
ArrayList<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
while(stdin.hasNext()) {
String[] str = stdin.nextLine().split("[\\s,]+");
ArrayList<Integer> inner = new ArrayList<Integer>();
for(int i = 0; i < str.length; i++) {
int value = Integer.parseInt(str[i]);
inner.add(value);
if(value > nodeCount && i != str.length - 1){
nodeCount = value;
}
}
list.add(inner);
}
int adjMatrix[][] = new int[nodeCount + 1][nodeCount + 1];
for(ArrayList<Integer> inner : list){
adjMatrix[inner.get(0)][inner.get(1)] += 1;
}
for(int i = 0; i < nodeCount; i++){
for(int j = 0; j < nodeCount; j++){
System.out.print(adjMatrix[i][j] + " ");
}
System.out.println();
}
}
Maybe you should use something like this as a starting point.
public class AdjacencyMatrix {
public static void main(String... args) {
List<Edge> edges = readFromStdIn();
Graph graph = new Graph(edges);
int[][] adjacencyMatrix = graph.getAdjacencyMatrix();
printMatrix(adjacencyMatrix);
}
private static List<Edge> readFromStdIn() {
List<Edge> edges = new ArrayList<Edge>();
try (Scanner scanner = new Scanner(System.in)) {
boolean readOn = true;
while (scanner.hasNext() && readOn) {
String[] strings = scanner.nextLine().split("[\\s,]+");
if (strings.length == 3) {
edges.add(new Edge(Integer.parseInt(strings[0]), Integer.parseInt(strings[1]),
Integer.parseInt(strings[2])));
} else {
readOn = false;
}
}
}
return edges;
}
private static void printMatrix(int[][] matrix) {
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
}
}
class Edge {
final int source;
final int destination;
final int weight;
Edge(int source, int destination, int weight) {
this.source = source;
this.destination = destination;
this.weight = weight;
}
}
class Graph {
final List<Edge> edges;
Graph(List<Edge> edges) {
this.edges = edges;
}
public int[][] getAdjacencyMatrix() {
int n = getNodeCount();
int[][] matrix = new int[n][n];
for (Edge e : edges) {
matrix[e.source][e.destination] = 1;
// directed graph?
matrix[e.destination][e.source] = 1;
}
return matrix;
}
int getNodeCount() {
int maxNodeNumber = 0;
for (Edge edge : edges) {
if (edge.source > maxNodeNumber) {
maxNodeNumber = edge.source;
}
if (edge.destination > maxNodeNumber) {
maxNodeNumber = edge.destination;
}
}
return maxNodeNumber + 1;
}
}
It introduces some classes to add some structure to the code, avoids lists when the array length is known.
Besides: it will not create entries with values greater than 1, if edges are contained multiple times.

NZEC error on Hackerearth in java

I am getting NZEC exception in java for below code on hackerearth. Can anyone please help?
Added the try catch block as well
import java.util.HashMap;
import java.util.Scanner;
class TestClass {
public static void main(String args[]) throws Exception {
try {
Scanner sc = new Scanner(System.in);
String S = new String();
HashMap<Long, String> hm = new HashMap<>();
S = sc.nextLine();
int len = sc.nextInt();
long[] q = new long[len];
for (int i = 0; i < len; i++) {
q[i] = sc.nextLong();
}
Long key = (long) 1;
for (int i = 0; i < S.length(); i++) {
for (int j = i + 1; j <= S.length(); j++) {
hm.put(key++, S.substring(i, j));
}
}
for (int i = 0; i < len; i++) {
if (q[i] <= hm.size())
System.out.println(hm.get(q[i]));
else {
System.out.println(-1);
}
}
} catch (Exception e) {
}
}
}
It mostly occurs when negative array index is accesed or the program which we have written takes up more space than the allocated memory for our program to run.

Sorting strings alphabetically in an array. Java

I have to sort strings in an array for a school project. Our teacher won't allow us to use array,sort().
i have to use 2 sort methods but they aren't working too well.
The first one returns double of each value. ie John, jack, adam, tom will return adam,adam,jack,jack,john,john,tom,tom.
public static void sort() {
inputFileNames();//inputs list of names from a file.
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
if (stArr[i].compareTo(stArr[j])>0) {
temp = stArr[i];
stArr[i] = stArr[j];
stArr[j] = temp;
}
}
}
display("The names are: ");// method to display array
System.out.println("");
}
the second sort doesn' run:
public static void bubbleSort() {
inputFileNames();
for (int i = size - 1; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
if (stArr[j].compareTo(stArr[j+1])>0) {
temp = stArr[j];
stArr[j] = stArr[j + 1];
stArr[j + 1] = temp;
}
}
}
display("The names are: ");
System.out.println("");
}
input and display:
static void display(String heading) {
System.out.println(heading + "\n");
for (int i = 0; i < size; i++) {
System.out.println(stArr[i]);
}
}
static void inputFileNames() {
try {
Scanner scFile = new Scanner(new File("Names.txt"));
while (scFile.hasNext()) {
stArr[size] = scFile.nextLine();
size++;
}
} catch (FileNotFoundException ex) {
System.out.println("File not found.");
}
}
/* package codechef; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Codechef
{
public static void main (String[] args) throws java.lang.Exception
{ Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int i,j;
String[] stArr = new String[n];
for(i=0;i<n;i++)
{
stArr[i]=sc.next();
// System.out.println(stArr[i]);
}
//inputs list of names from a file.
for (i = 0; i < n ; i++) {
for (j = i+1 ; j < n; j++) {
if (stArr[i].compareTo(stArr[j])>0)
{
String temp = stArr[i];
stArr[i] = stArr[j];
stArr[j] = temp;
// System.out.println(stArr[i]);
// System.out.println(stArr[j]);
}
}
}
for(i=0;i<n;i++)
{
System.out.println(stArr[i]);
}
// your code goes here
}
}
This Is the answer for first code. I am not good in file handling so you have to use your input method. I know Scanner thats why i have used here.
In Your Second Example Your j loop is wrong it should be for ( j = 0; j <= i-1; j++). And Please Mark It as answer if your problem is solved

Sorting of array

This is the text file:
1,2,8,4,5,6,7,7,
3,4,5,6,7,8,
5,6,7,8,9,9,
1,2,3,4,5,8,9,0
After ignoring the 1st column:
2,8,4,5,6,7,7,
4,5,6,7,8,
6,7,8,9,9,
2,3,4,5,8,9,0
I want to sort the array in descending order but I can't get it to work. This is the code that I have done so far:
Scanner scanner = new Scanner(new File("test.txt"));
int row = 0;
int col = 0;
while (scanner.hasNextLine())
{
String currentline = scanner.nextLine();
row++;
String[] items = currentline.split(",");
int[] intitems = new int[items.length];
for (int i = 1; i < items.length; i++)
{
intitems[i] = Integer.parseInt(items[i]);
System.out.print(intitems[i] + " ");
int temp = 0;
for (int j = 2; j < (items.length - i); j++)
{
temp = intitems[j - 1];
intitems[j - 1] = intitems[j];
intitems[j] = temp;
}
col = i;
}
col++;
System.out.println();
System.out.println("After sort: " + intitems);
System.out.println();
}
System.out.println("Row: " +row);
No need to complicate things:
for (int i = 1; i < items.length; i++) {
intitems[i - 1] = Integer.parseInt(items[i]);
}
Arrays.sort(intitems); // Ascending
Arrays.sort(intitems, Collections.reverseOrder()); // Descending
But if you really want to use a loop to sort the array (bubblesort) you need to compare the items you switch:
for (int i = 0; i < intitems.length - 1; i++) {
for(int j = i + 1; j < intitems.length; j++) {
if (intitems[i] > intitems[j]) {
int temp = intitems[j];
intitems[j] = intitems[i];
intitems[i] = temp;
}
}
}
If you want it sorted in descending order then just change the greater than (>) comparison to a lesser than (<) comparison:
if (intitems[i] < intitems[j]) {
private static void sortInDescending(int[] arrayObj)
{
int n = arrayObj.length;
int temp = 0;
for(int i=0; i < n; i++)
{
for(int j=1; j < (n-i); j++)
{
if(arrayObj[j-1] < arrayObj[j])
{
temp = arrayObj[j-1];
arrayObj[j-1] = arrayObj[j];
arrayObj[j] = temp;
}
}
}
}
Call method
sortInDescending(arrayinput);
You can use the Arrays.sort() with a custom comparator to make it descending.
String[] items = currentLine.split(",");
Integer[] intItems = new Integer[items.length];
for(int i=0; i<intItems.length; ++i) {
intItems[i] = Integer.parseInt(items[i]);
}
Comparator<Integer> comparator = new Comparator<Integer>() {
#Override
public int compare(Integer left, Integer right) {
return -Integer.compare(left, right);
}
};
Arrays.sort(intItems, comparator);
System.out.println(Arrays.toString(intItems));
}
Or you can sort the array in ascending order and reverse the array.
Arrays.sort(intItems);
Integer[] descending = new Integer[intItems.length];
int length = descending.length;
for(int i=0; i<length; ++i) {
descending[i] = intItems[length - 1 - i];
}
System.out.println(Arrays.toString(descending));
Other answers contain the bubble sort algorithm, where one element is compared to its successor. If the sort condition matches, then they get swapped. A slightly faster solution is insertion sort: in essence, it finds the maximal (minimal) value of the array and puts it to the front. There the implementation could look like this:
static int[] array = {2,8,4,5,6,7,7,};
public static void insertionSort(final int[] array) {
for(int i = 0; i < array.length; i++){
int maxValueIndex = findMaxValue(array, i);
int temp = array[i];
array[i] = array[maxValueIndex];
array[maxValueIndex]=temp;
}
}
private static int findMaxValue(final int[] array, int index) {
int value = Integer.MIN_VALUE;
for (int i = index; i < array.length; i++) {
if (array[i] > value) {
value = array[i];
index = i;
}
}
return index;
}
public static void main(final String[] args){
insertionSort(array);
System.out.println(Arrays.toString(array));
}
There you go :
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class SortTXT {
static File fout;
public static void main(String[] args) {
fout = new File("text.txt");
if (!fout.isFile())
{
System.out.println("text.txt - Parameter is not an existing file");
}
else
{
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(fout)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = null;
try {
while ((line = br.readLine()) != null) {
if (line.length()>2)
{
line.trim();
// crete an array from the line - seperate by ","
List<String> list = new ArrayList<String>(Arrays.asList(line.split(",")));
// remove the 1st number
list.remove(0);
//sorting the list
Collections.sort(list);
System.out.println();
System.out.println("After sort: ");
// print out the sorted array
for(String temp: list){
System.out.print("," + temp);
}
}
}
} catch (IOException e) {
}
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Hope This Helps :)
Dave.

Sort strings in an array based on length

I have the below program for sorting Strings based on length. I want to print the shortest element first. I don't want to use Comparator or any API to do this. Where I am going wrong?
public class SortArrayElements {
public static void main(String[] args) {
String[] arr = new String[]{"Fan","dexter","abc","fruit","apple","banana"};
String[] sortedArr = new String[arr.length];
for(int i=0;i<sortedArr.length;i++)
{
sortedArr[i] = compareArrayElements(arr);
}
System.out.println("The strings in the sorted order of length are: ");
for(String sortedArray:sortedArr)
{
System.out.println(sortedArray);
}
}
public static String compareArrayElements(String[] arr) {
String temp = null;
for(int i=0;i<arr.length-1;i++)
{
temp = new String();
if(arr[i].length() > arr[i+1].length())
temp = arr[i+1];
else
temp = arr[i];
}
return temp;
}
}
If you really want to learn Java: use a Comparator. Any other way is bad Java code.
You can however rewrite the Comparator system if you want, it will teach you about proper code structuring.
For your actual code, here are some hints:
Using the proper algorithm is much more important than the Language you use to code. Good algorithms are always the same, no matter the language.
Do never do new in loops, unless you actually need to create new objects. The GC says "thanks".
Change the compareArrayElements function to accept a minimum size and have it return the smallest String with at least minimum size.
You could cut out those Strings that you have considered to be the smallest (set them to null), this will however modify the original array.
Use bubble sort, but instead of comparing ints, just compare String lengths.
I won't write the code for you. You will have to do a little bit of research on this algorithm. Google is your best friend as a programmer.
Good luck.
References:
Bubble sort in Java
Sorting an array of strings
Implement bubbleSort() and swap(). My implementations mutate the original array, but you can modify them to make a copy if you want.
public class SortArrayElements {
public static void main(String[] args) {
String[] arr = new String[]{"Fan", "dexter", "abc", "fruit", "apple", "banana"};
bubbleSort(arr);
System.out.println("The strings in the sorted order of length are: ");
for (String item : arr) {
System.out.println(item);
}
}
// Mutates the original array
public static void bubbleSort(String[] arr) {
boolean swapped = false;
do {
swapped = false;
for (int i = 0; i < arr.length - 1; i += 1) {
if (arr[i].length() > arr[i + 1].length()) {
swap(arr, i, i + 1);
swapped = true;
}
}
} while (swapped);
}
// Mutates the original array
public static void swap(String[] arr, int index0, int index1) {
String temp = arr[index0];
arr[index0] = arr[index1];
arr[index1] = temp;
}
}
Okay, there is the code completely based on loops and on bubble sort. No sets are there as you wanted it. This is a pure loop program so you could understand the nested loops, plus it doesn't change the index or something of the string
import java.util.*;
class strings {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ArrayList<String> a = new ArrayList<String>(2);
System.out.println("Start entering your words or sentences.");
System.out.println("Type stop to stop.");
String b;
int c = 0, d;
do {
b = in.nextLine();
b = b.trim();
a.add(b);
c++;
}
while (!b.equalsIgnoreCase("stop"));
if (c > 1)
a.remove(a.size() - 1);
System.out.println("Choose the sort you want. Type the corresponding
number");
System.out.println("1. Ascending");
System.out.println("2. Descending");
int sc=in.nextInt();
switch(sc) {
case 1: {
int sag[] = new int[a.size()];
for (int jk = 0; jk < a.size(); jk++) {
b = a.get(jk);
c = b.length();
sag[jk] = c;
}
int temp;
for (int i = 0; i < a.size() - 1; i++) {
for (int j = 0; j < a.size() - 1; j++) {
if (sag[j] > sag[j + 1]) {
temp = sag[j + 1];
sag[j + 1] = sag[j];
sag[j] = temp;
}
}
}
ArrayList saga = new ArrayList();
for (int i = 0; i < sag.length; i++) {
saga.add(sag[i]);
}
for (int i = 0; i < saga.size(); i++) {
for (int j = i + 1; j < saga.size(); j++) {
if (saga.get(i).equals(saga.get(j))) {
saga.remove(j);
j--;
}
}
}
for (int i = 0; i < saga.size(); i++) {
for (int j = 0; j < a.size(); j++) {
String jl = a.get(j);
if (saga.get(i).equals(jl.length()))
System.out.println(jl);
}
}
break;
}
case 2: {
int sag[] = new int[a.size()];
for (int jk = 0; jk < a.size(); jk++) {
b = a.get(jk);
c = b.length();
sag[jk] = c;
}
int temp;
for (int i = 0; i < a.size() - 1; i++) {
for (int j = 0; j < a.size() - 1; j++) {
if (sag[j] < sag[j + 1]) {
temp = sag[j + 1];
sag[j + 1] = sag[j];
sag[j] = temp;
}
}
}
ArrayList saga = new ArrayList();
for (int i = 0; i < sag.length; i++) {
saga.add(sag[i]);
}
for (int i = 0; i < saga.size(); i++) {
for (int j = i + 1; j < saga.size(); j++) {
if (saga.get(i).equals(saga.get(j))) {
saga.remove(j);
j--;
}
}
}
for (int i = 0; i < saga.size(); i++) {
for (int j = 0; j < a.size(); j++) {
String jl = a.get(j);
if (saga.get(i).equals(jl.length()))
System.out.println(jl);
}
}
break;
}
}
}
}
For instance, the following:
ArrayList<String> str = new ArrayList<>(
Arrays.asList(
"Long", "Short", "VeryLong", "S")
);
By lambda:
str.sort((String s1, String s2) -> s1.length() - s2.length());
By static Collections.sort
import static java.util.Collections.sort;
sort(str, new Comparator<String>{
#Override
public int compare(String s1, String s2) {
return s1.lenght() - s2.lenght()
}
});
Both options are implemented by default sort method from List interface
Let's take a following array of String inputArray = ["abc","","aaa","a","zz"]
we can use Comparator for sorting the given string array to sort it based on length with the following code:
String[] sortByLength(String[] inputArray) {
Arrays.sort(inputArray, new Comparator<String>(){
public int compare(String s1, String s2){
return s1.length() - s2.length();
}
});
return inputArray;
}
//sort String array based on length
public class FirstNonRepeatedString {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Please Enter your String");
String str = in.nextLine();
String arrString[] = str.split("\\s");
arrString = sortArray(arrString);
System.out.println("Sort String ");
for(String s:arrString){
System.out.println(s);
}
}
private static String[] sortArray(String[] arrString) {
int length = arrString.length;
String s;
for (int i = 0; i < length ; i++) {
s= new String();
for(int j = 0; j < length; j++ ){
if(arrString[i].length()< arrString[j].length()){
s = arrString[i];
arrString[i] = arrString[j];
arrString[j] = s;
}
}
}
return arrString;
}
}
import java.util.*;
public class SortStringBasedOnTheirLength {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("Enter String:");
String str=sc.nextLine();
String[] str1=str.split("\\s");
for(int i=0;i<str1.length;i++)
{
for(int j=i+1;j<str1.length;j++)
{
if(str1[i].length()>str1[j].length())
{
String temp= str1[i];
str1[i]=str1[j];
str1[j]=temp;
}
}
}
for(int i=0;i<str1.length;i++)
{
System.out.print(str1[i]+" ");
}
}
}

Categories

Resources