I am trying to solve the following question HackerRank Java 1D Array
I have come up with the following backtracking approach.
import java.util.Scanner;
public class Solution {
static int arr[];
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int T = sc.nextInt();
for (int j= 0; j < T; j++) {
int n = sc.nextInt();
arr = new int[n];
int m = sc.nextInt();
for (int k = 0; k< n; k++) {
arr[k]= sc.nextInt();
}
if(canReach(0,arr.length,m))
System.out.println("YES");
else
System.out.println("NO");
}
}
public static boolean canReach(int src,int dest,int m)
{
if(src>=(dest-1)||(src+m)>=dest)
return true;
if(isValidDest(src+1)&&canReach(src+1, dest, m))
return true;
if(isValidDest(src-1)&&canReach(src-1, dest, m))
return true;
if(isValidDest(src+m)&&canReach(src+m, dest, m))
return true;
return false;
}
private static boolean isValidDest(int dest) {
if(((dest>=0&&dest<arr.length)&&(arr[dest]==0)))
return true;
return false;
}
}
But I am getting a stack-overflow error for the following test case 0 0 1 1 1 0.
Could anyone help me out on how to avoid this stack-overflow error, while keeping intact the backtracking approach.
Modified code (solution)
import java.util.Scanner;
public class Solution {
static int arr[];
static boolean isDestVisited[];
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int T = sc.nextInt();
for (int j= 0; j < T; j++) {
int n = sc.nextInt();
arr = new int[n];
isDestVisited = new boolean[n];
int m = sc.nextInt();
for (int k = 0; k< n; k++) {
arr[k]= sc.nextInt();
}
if(canReach(0,arr.length,m))
System.out.println("YES");
else
System.out.println("NO");
}
}
public static boolean canReach(int src,int dest,int m)
{
if(src>=(dest-1)||(src+m)>=dest)
return true;
if(isDestVisited[src]==true)
return false;
isDestVisited[src]=true;
if(isValidDest(src+1)&&canReach(src+1, dest, m))
return true;
if(isValidDest(src-1)&&canReach(src-1, dest, m))
return true;
if(isValidDest(src+m)&&canReach(src+m, dest, m))
return true;
isDestVisited[src]=false;
return false;
}
private static boolean isValidDest(int dest) {
if(((dest>=0&&dest<arr.length)&&(arr[dest]==0)))
return true;
return false;
}
}
In recursive algo you must to avoid processing of same state twice
if (src >= dest)
return true;
if (thisPositionAlreadyTested[src])
return false;
thisPositionAlreadyTested[src] = true;
if ( ...
or you can reuse arr[] content for same purpose if you can modify it
Related
I am trying to write a program that creates an array and fill it with int numbers(first method). In the end, it is supposed to see if a specific number is given in the array(second method). The problem is that the program does not run my if loops. I do not know why.
The variable x is the number the program is looking for in the array and pos the position of the number in the array
public class Program {
static int [] numbers= new int[100];
public static void main(String [] args) {
PrintWriter out = new PrintWriter(System.out);
arrayConstruction();
test(out);
out.flush();
}
public static void arrayConstruction() {
int x = 0;
for (int i = 0; i < numbers.length; i++) {
numbers[i] = x;
x++;
}
}
public static void test(PrintWriter out) {
int x = 17;
int pos = 0;
if(pos != numbers.length) {
if(numbers[pos] == x) {
out.println("The number was found!");
out.flush();
}
pos++;
}
else if(pos == numbers.length) {
out.println("The number does not exist!");
out.flush();
}
}
}
You forgot to add a loop to the test method, so it checks the first array's item only. E.g. you can use while loop.
public static void test(PrintWriter out) {
int x = 17;
int pos = 0;
while (true) {
if (pos != numbers.length) {
if (numbers[pos] == x) {
out.println("The number was found!");
return;
}
pos++;
} else if (pos == numbers.length) {
out.println("The number does not exist!");
return;
}
}
}
I think you should redesign your code by splitting different activities with separate methods. It makes your code clear to understand.
public class Main {
public static void main(String[] args) {
int[] arr = createArray(100);
System.out.println(isNumberExist(arr, 17) ? "The number was found!"
: "The number does not exist!");
}
public static int[] createArray(int total) {
int[] arr = new int[total];
Random random = new Random();
for (int i = 0; i < arr.length; i++)
arr[i] = random.nextInt(arr.length);
return arr;
}
public static boolean isNumberExist(int[] arr, int x) {
for (int i = 0; i < arr.length; i++)
if (arr[i] == x)
return true;
return false;
}
}
You should add a while loop to your test method, like this:
public static void test(PrintWriter out) {
int x = 17;
int pos = 0;
while(pos < numbers.length) {
if(numbers[pos] == x) {
out.println("The number was found!");
out.flush();
break;
}
pos++;
}
if(pos == numbers.length) {
out.println("The number does not exist!");
out.flush();
}
}
In your method, the if statement will only be executed once.
I have opened an account for Ridit, one of 7-years-old students learning Java at SPOJ. The first task i gave to him was PALIN -The Next Palindrome. Here is the link to this problem- PALIN- The next Palindrome- SPOJAfter i explained it to him, he was able to solve it mostly except removing the leading zeros, which i did. Following is his solution of the problem -
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
Scanner in = new Scanner(System.in);
int t = Integer.parseInt(in.nextLine());
String[] numbersInString = new String[t];
for (int i = 0; i <t; i++) {
String str = in.nextLine();
numbersInString[i] = removeLeadingZeros(str);
}
for (int i = 0 ; i<t; i++) {
int K = Integer.parseInt(numbersInString[i]);
int answer = findTheNextPalindrome(K);
System.out.println(answer);
}
}catch(Exception e) {
return;
}
}
static boolean isPalindrome(int x) {
String str = Integer.toString(x);
int length = str.length();
StringBuffer strBuff = new StringBuffer();
for(int i = length - 1;i>=0;i--) {
char ch = str.charAt(i);
strBuff.append(ch);
}
String str1 = strBuff.toString();
if(str.equals(str1)) {
return true;
}
return false;
}
static int findTheNextPalindrome(int K) {
for(int i = K+1;i<9999999; i++) {
if(isPalindrome(i) == true) {
return i;
}
}
return -1;
}
static String removeLeadingZeros(String str) {
String retString = str;
if(str.charAt(0) != '0') {
return retString;
}
return removeLeadingZeros(str.substring(1));
}
}
It is giving correct answer in Eclipse on his computer, but it is failing in SPOJ. If someone helps this little boy in his first submission, it will definitely make him very happy. I couldn't find any problem with this solution... Thank you in advance...
This might be helpful
import java.io.IOException;
import java.util.Scanner;
public class ThenNextPallindrom2 {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
int t = 0;
Scanner sc = new Scanner(System.in);
if(sc.hasNextInt()) {
t = sc.nextInt();
}
sc.nextLine();
int[] arr, arr2;
while(t > 0) {
t--;
String s = sc.nextLine();
arr = getStringToNumArray(s);
if(all9(arr)) {
arr2 = new int[arr.length + 1];
arr2[0] = 1;
for(int i=0;i<arr.length;i++) {
arr2[i+1] = 0;
}
arr2[arr2.length -1] = 1;
arr = arr2;
} else{
int mid = arr.length/ 2;
int left = mid-1;
int right = arr.length % 2 == 1 ? mid + 1 : mid;
boolean left_small = false;
while(left >= 0 && arr[left] == arr[right]) {
left--;
right++;
}
if(left < 0 || arr[left] < arr[right]) left_small = true;
if(!left_small) {
while(left >= 0) {
arr[right++] = arr[left--];
}
} else {
mid = arr.length/ 2;
left = mid-1;
int carry = 1;
if(arr.length % 2 == 0) {
right = mid;
} else {
arr[mid] += carry;
carry = arr[mid]/10;
arr[mid] %= 10;
right = mid + 1;
}
while(left >= 0) {
arr[left] += carry;
carry = arr[left] / 10;
arr[left] %= 10;
arr[right++] = arr[left--];
}
}
}
printArray(arr);
}
}
public static boolean all9(int[] arr) {
for(int i=0;i<arr.length;i++) {
if(arr[i] != 9)return false;
}
return true;
}
public static void printArray(int[] arr) {
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]);
}
System.out.println();
}
public static int[] getStringToNumArray(String s) {
int[] arr = new int[s.length()];
for(int i=0; i<s.length();i++) {
arr[i] = Integer.parseInt(String.valueOf(s.charAt(i)));
}
return arr;
}
}
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 5 years ago.
I am working on a program that will solve find a path in a maze. The maze is represented by 0's, 1's and an E to represent the Exit. The maze is represented by a 20x30 (0's represent the path, 1's represent walls). I am using a stack to keep track of a previous usable location.
I think I have most of the code figured out, but whenever i try to run it, i get an ArrayIndexOutOfBoundsException. I think the main problem is that there are no defined walls around the border. Maybe surround the maze with a border of 1's?
My code is as follows:
import java.util.*;
import java.io.*;
public class MazeGenerator {
//main
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
int userRow, userCol;
MazeGenerator maze = new MazeGenerator();
maze.fillArray();
maze.print();
System.out.println();
//asking for user starting position
System.out.print("What row would you like to start in?: " );
userRow = sc.nextInt();
while(userRow > 29 || userRow < 0) {
System.out.print("INVALID INPUT! PLEASE ENTER VALUES BETWEEN 0 - 29 INCLUSIVE: " );
userRow = sc.nextInt();
}
System.out.println();
System.out.print("What column would you like to start in? ");
userCol = sc.nextInt();
while(userCol > 19 || userCol < 0) {
System.out.print("INVALID INPUT! PLEASE ENTER VALUES BETWEEN 0 - 19 INCLUSIVE: " );
userCol= sc.nextInt();
}
System.out.println("\n\nFind a path using a stack: ");
//maze.userStart(userRow,userCol);
maze.setUserRow(userRow);
maze.setUserColumn(userCol);
maze.solveStack();
}
//methods for creating maze
public static final int ROW = 30;
public static final int COLUMN = 20;
public int userRow = 0;
public int userColumn = 0;
private static String[][] maze = new String[ROW][COLUMN];
public void fillArray() throws IOException {
File file = new File("maze.txt");
FileReader reader = new FileReader(file);
BufferedReader buff = new BufferedReader(reader);
for(int counter1 = 0; counter1 < ROW; counter1++) {
String l = buff.readLine();
for(int counter2 = 0; counter2 < COLUMN; counter2++) {
maze[counter1][counter2] = String.valueOf(l.charAt(counter2));
}
}
buff.close();
}
public void print() throws IOException {
System.out.printf("%-4s", ""); //spaces column
for (int counter = 0; counter < COLUMN; counter++){
System.out.printf("%-4d",counter); //print the column number
}
System.out.println();
for(int counter1 = 0; counter1 < maze.length; counter1++) { //loop for printing rows
System.out.printf("%-4d",counter1); //print row number
for(int counter2 = 0; counter2 < maze[counter1].length; counter2++) { //loop for printing columns
System.out.printf("%-4s", maze[counter1][counter2]); //printing values of maze
}
System.out.println(); // new line
}
}
public int size() {
return maze.length;
}
public void setUserRow (int userRow) {
this.userRow = userRow;
}
public void setUserColumn (int userColumn) {
this.userColumn = userColumn;
}
public int getUserRow() {
return userRow;
}
public int getUserColumn() {
return userColumn;
}
public String mark(int row, int col, String value) {
assert(inMaze(row,col));
String temp = maze[row][col];
maze[row][col] = value;
return temp;
}
public String mark (MazePosition pos, String value) {
return mark(pos.row(), pos.col(), value);
}
public boolean isMarked(int row, int col) {
assert(inMaze(row,col));
return (maze[row][col].equals("+"));
}
public boolean isMarked(MazePosition pos) {
return isMarked(pos.row(), pos.col());
}
public boolean Clear(int row, int col) {
assert(inMaze(row,col));
return (maze[row][col] != "1" && maze[row][col] != "+");
}
public boolean Clear(MazePosition pos) {
return Clear(pos.row(), pos.col());
}
//true if cell is within maze
public boolean inMaze(int row, int col) {
if (row >= 0 && col<size() && row>= 0 && col<size()) {
return true;
}
else if (row < 0 && col<size() && row >= 0 && col<size()) {
return false;
}
else return false;
}
//true if cell is within maze
public boolean inMaze(MazePosition pos) {
return inMaze(pos.row(), pos.col());
}
public boolean Done( int row, int col) {
return (maze[row][col].equals("E"));
}
public boolean Done(MazePosition pos) {
return Done(pos.row(), pos.col());
}
public String[][] clone() {
String[][] copy = new String[ROW][COLUMN];
for (int counter1 = 0; counter1 < ROW; counter1++) {
for (int counter2 = 0; counter2 < COLUMN; counter2++) {
copy[counter1][counter2] = maze[counter1][counter2];
}
}
return copy;
}
public void solveStack() throws IOException {
//save the maze
String[][] savedMaze = clone();
//declare the locations stack
Stack<MazePosition> candidates = new Stack<MazePosition>();
//insert the start
candidates.push(new MazePosition(userRow,userColumn));
MazePosition current, next;
while (!candidates.empty()) {
//get current position
current = candidates.pop();
if (Done(current)) {
break;
}
//mark the current position
mark(current, "S");
//put its neighbors in the queue
next = current.north();
if (inMaze(next) && Clear(next)) candidates.push(next);
next = current.east();
if (inMaze(next) && Clear(next)) candidates.push(next);
next = current.west();
if (inMaze(next) && Clear(next)) candidates.push(next);
next = current.south();
if (inMaze(next) && Clear(next)) candidates.push(next);
}
if (!candidates.empty())
System.out.println("You got it!");
else System.out.println("You're stuck in the maze!");
print();
}
class MazePosition {
public int row;
public int col;
public MazePosition(int row, int col) {
this.row = row;
this.col = col;
}
public int row() { return row; }
public int col() { return col; }
public void print() {
System.out.println("(" + row + "," + col + ")");
}
//positions
public MazePosition north() {
return new MazePosition(row-1, col);
}
public MazePosition south() {
return new MazePosition(row+1, col);
}
public MazePosition east() {
return new MazePosition(row, col+1);
}
public MazePosition west() {
return new MazePosition(row, col-1);
}
};
}
The error is as follows:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at MazeGenerator.Clear(MazeGenerator.java:137)
at MazeGenerator.Clear(MazeGenerator.java:141)
at MazeGenerator.solveStack(MazeGenerator.java:217)
at MazeGenerator.main(MazeGenerator.java:40)
i think you're doing a mistake in inMaze(int row, int col) method. I'll try to correct it for you
public boolean inMaze(int row, int col) {
if (row >= 0 && col >= 0 && row < getWidth() && col < getHeight() ) {
return true;
}
return false;
}
therefore you have to change the size() method into getWidth() and getHeight()
public int getWidth(){
return maze[0].length;
}
public int getHeight(){
return maze.length;
}
I am having trouble implementing the insertionSort() method.
import java.util.Random;
import java.util.Arrays;
public class Lab6 {
static final int SIZE = 100;
static int[] values = new int[SIZE];
static void initValues() {
Random rand = new Random();
for(int i =0; i< SIZE;i++) {
values[i] = rand.nextInt(100);// limit to 100
}
}
static boolean isSorted() {
boolean sorted = true;
for(int i=0;i<SIZE-1;i++) {
if(values[i] > values[i+1]){
sorted = false;
}
}
return sorted;
}
static void swap(int index1, int index2) {
int temp = values[index1];
values[index1] = values[index2];
values[index2] = temp;
}
static void insertElement(int endIndex) {
// FILL IN CODE HERE
boolean finished = false;
int current = endIndex;
boolean moretoSearch = true;
while (moretoSearch && !finished){
if (values[current] < values[current-1]){
swap(current, current-1);
current--;
}
else
finished = true;
}
}
I am also not sure if this method "insertElementBinary(int endIndex)" is correctly implemented;
static void insertElementBinary(int endIndex) {
//FILL IN CODE HERE FOR BINARY SEARCH INSERTIONSORT
boolean finished = false;
int current = endIndex;
boolean moretoSearch = true;
while (moretoSearch && !finished){
if (values[current] < values[current-1]){
swap(current, current-1);
current--;
moretoSearch = (current != endIndex);
}
else
finished = true;
}
}
This is where my major problems are:
static void insertionSort() {
//FILL IN CODE HERE
for (int i =0; i < SIZE; i++){
insertElement(i);
insertElementBinary(i);
}
}
The rest of this is good:
public static void main(String[] args) {
Lab6.initValues(); // generate the random array
System.out.println(Arrays.toString(values));
System.out.println(isSorted());
insertionSort();
System.out.println(Arrays.toString(values));
System.out.println(isSorted());
}
}
You're very close to having it correct.
In your insertElement(int endIndex) method, you need to make sure your current > 0, shown below, or else you're going to have an array out of bounds error.
static void insertElement(int endIndex) {
boolean finished = false;
int current = endIndex;
boolean moretoSearch = true;
while (moretoSearch && !finished && current > 0){
if (values[current] < values[current-1]){
swap(current, current-1);
current--;
}
else
finished = true;
}
}
The same fix applies to your insertElementBinary(int endIndex) method. You can test both by commenting out insertElement(i) or insertElementBinary(i) in the insertionSort() method. Both will work fine now.
I'm trying to implement KMP algorithm. My algorithm works correctly with the following example
Text: 121121
Pattern: 121
Result: 1,4
But when Text is 12121 and pattern is the same as above, result just: 1. I don't know if this is the problem of the algorithm or of my implementation?
Other example:
Text: 1111111111
Pattern: 111
Result: 1,4,7
My code is:
public class KMP {
public static void main(String[] args) throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String text = reader.readLine();
String pattern = reader.readLine();
search(text,pattern);
}
private static void search(String text,String pattern)
{
int[] Pi = Pi(pattern);
for (int i = 0,q=0; i <text.length()&&q<pattern.length() ; i++,q++) {
while (q>=0 && pattern.charAt(q)!=text.charAt(i))
{
q=Pi[q];
}
if(q==pattern.length()-1) {
System.out.println(i-pattern.length()+2);
q=Pi[q];
}
}
}
private static int[] Pi(String p) {
int[] Pi = new int[p.length()];
Pi[0]=-1;
int i=0;
int j=-1;
while (i<p.length()-1) {
while (j>=0 && p.charAt(j)!=p.charAt(i))
{
j=Pi[j];
}
i++;
j++;
if(p.charAt(j)==p.charAt(i)) Pi[i]=Pi[j];
else Pi[i]=j;
}
return Pi;
}
}
Hope help you.
public int strStr(String source, String target) {
if (source == null || target == null){
return -1;
}
if (source.isEmpty() && !target.isEmpty()){
return -1;
}
if (source.isEmpty() && target.isEmpty()){
return 0;
}
if (target.isEmpty()){
return 0;
}
int index = 0;
int compare_index = 0;
int compare_start_index = 0;
int compare_same_length = 0;
List<Integer> answers = new ArrayList<Integer>();
while (true){
if (compare_same_length ==0){
compare_start_index = compare_index;
}
if (source.charAt(compare_index) == target.charAt(index)){
compare_same_length++;
index++;
} else {
if (compare_same_length >0){
compare_index--;
}
compare_same_length = 0;
index = 0;
}
compare_index++;
if (compare_same_length == target.length()){
answers.add(compare_start_index+1);
compare_same_length=0;
index=0;
}
if (compare_index == source.length()){
//here are answers
for (int i = 0; i < answers.size(); i++) {
int value = answers.get(i);
}
return 1;
}
}
}