It was an interview question and I was asked to fix the code-->
Given a sorted array, I have to find the array index of the element if it is present, else I have to return -1. Following is my code:
public static int returnIndex(int[] a, int x) {
int n = a.length;
if (n == 0) {
return -1;
}
int l = 0;
int r = n - 1;
while (l < r) {
int m = (l + r) / 2;
if (a[m] > x) {
r = m - 1;
} else {
l = m;
}
}
if (a[l] == x) {
return l;
}
return -1;
}
Code works fine if I have to find the middle element but fails (goes into infinite loop) when I have to find any other element. Can anyone point out the mistake?
I am allowed to make only 3 modifications in this code.
Worst case Time Complexity-O(log(n))
Worst case Space Complexity-O(1)
You are trying binary search here. So you need to have 3 conditions. midValue > key, midValue < key and midValue == key. You are handling only 2. Also when midValue > key you need to add one to index. So modify your method like
public static int returnIndex(int[] a, int x) {
int n = a.length;
if (n == 0) {
return -1;
}
int l = 0;
int r = n - 1;
while (l < r) {
int m = (l + r) / 2;
if (a[m] > x) {
r = m - 1;
} else if(a[m] < x){
l = m + 1;
} else {
return m;
}
}
return -1;
}
If you are not doing it for an exercise you could achieve the same via Arrays.binarySearch() method.
I would it this way:
public static int returnIndex(int[] a, int x) {
int n = a.length;
if (n == 0) {
return -1;
}
int l = 0;
int r = n - 1;
while (l < r) {
int m = (l + r) / 2;
if (a[m] == x) {
return m;
}
if (a[m] > x) {
r = m - 1;
} else {
l = m + 1;
}
}
return -1;
}
Related
basically i have an integer n = 23456 and i want to swap the second and fourth digit, so i = 2 and j = 4. So the output would be 25436. I canĀ“t use any Java class, so I supose that one of the ways to do it is by divide the number on powers of 10 and keep the rest on a new variable.
this is what i have so far:
public static int powerOfTen(int n) {
int p = 10;
while(n-1 > 0) {
p = p*10;
n--;
}
return p;
}
public static int swapNum(int n, int i, int j) {
int swap = 1;
int count = numDigits(n);
int digit1 = nDigit(n, i);
int digit2 = nDigit(n, j);
if(i > j) {
swap = n/powerOfTen(i);
int rest = n%powerOfTen(i);
rest = rest/10;
swap = swap*powerOfTen(i);
}
}
Here's your code with some modifications:
public class Main
{
// Count the number of digits in an integer
static int numDigits(int n)
{
if (n == 0) return 1;
int count = 0;
while (n != 0) {
count++;
n /= 10;
}
return count;
}
// Reverse an integer
static int reverseNumber(int n)
{
int result = 0;
while (n != 0) {
result = result * 10 + n % 10;
n /= 10;
}
return result;
}
// Get the nth digit - from the left
static int nDigit(int n, int index)
{
n = reverseNumber(n);
for (int i = 0; i < index; i++) {
n /= 10;
}
return n % 10;
}
static int swapNum(int n, int i, int j)
{
// Make indexes 0-based
i = i - 1;
j = j - 1;
int count = numDigits(n);
int digit1 = nDigit(n, i);
int digit2 = nDigit(n, j);
int result = 0;
for (int k = count - 1; k >= 0; --k) {
int digit;
// Get the correct digit, i, j, or current
if (k == i) digit = digit2;
else if (k == j) digit = digit1;
else digit = n % 10;
result = result * 10 + digit;
n /= 10;
}
return reverseNumber(result);
}
public static void main(String[] args) {
System.out.println(swapNum(12345678 , 4, 5));
}
}
You can't use any class? what about convert number to char array, swap and parse it back?
// helper function to convert char array to int
public static int parseInt(char[] chars) {
int result = 0; // accumulator
int idx_value = 1; // power of ten counter
for (int i = chars.length - 1; i >= 0; i--) { // loop from tail to head
// char - '0' mean it will convert '0' to 0 and '1' will be 1 so on.
result += (chars[i] - '0') * idx_value;
idx_value *= 10;
}
return result;
}
public static int swapNum(int n, int i, int j) {
// convert number to char array
char[] chars = ("" + n).toCharArray();
// use zero based index
i-=1;j-=1;
// perform swap
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
// convert char array back to int
return parseInt(chars);
}
Ok in this method I am supposed to compute the factorial using only the evens. So for example if I inputed 7 for n I would expect 6*4*2 = 48. I am supposed to fix the code so it will work. I have tried for like an hour now and don't know what I am doing wrong. Here is my code:
int p07EvenFactorial(int n) {
if (n % 2 == 1) {
n--;
}
int fact = 1;
for (int i = n; i > 0; i--) {
fact = fact + 2 * i;
}
return fact;
}
how about
int p07EvenFactorial(int n) {
if (n % 2 == 1) {
n--;
}
int fact = 1;
for (int i = 2; i <= n; i = i + 2) {
fact = fact * i;
}
return fact;
}
How about this
public int fact(int n) {
if(n % 2 ==1){
n = n -1;
}
if(n == 0){
return 1;
} else {
return n*fact(n-2);
}
}
I am trying to do the following program in Java where I'm writing a recursive and an iterative method to compute the sum of all odd numbers from n to m
import java.util.Scanner;
public class AssignmentQ7 {
public static int recursivesum(int n, int m){
if (n < m){
int s = n;
s += recursivesum(n+2, m);
} else{
if(m < n){
int s = m;
s += recursivesum(m+2, n);
}
}
return s;
}
public static int iterativesum(int n, int m){
if(n < m){
int s = n;
for(int i = n; i <= m; i += 2){
s += i;
return s;
}
} else
if(m < n){
int s = m;
for(int i = m; i <= n; i += 2){
s += i;
return s;
}
}
}
public static void main(String args[]){
int n,m;
Scanner in = new Scanner(System.in);
System.out.println("Enter two numbers: ");
n = in.nextInt();
m = in.nextInt();
while(n%2 == 0){
System.out.println("Enter the first number again: ");
n = in.nextInt();
}
while(m%2 == 0){
System.out.println("Enter the second number again: ");
m = in.nextInt();
}
System.out.println("The answer of the recursive sum is: " + recursivesum(n,m));
System.out.println("The answer of the iterative sum is: " + iterativesum(n,m));
}
}
I'm getting an error cannot find symbol - variable enter code heres. I don't know what's wrong! Can anyone help please?
This method is the problem:
public static int recursivesum(int n, int m) {
if (n < m) {
int s = n; // Variable declared here... scoped to the if
s += recursivesum(n+2, m);
} else {
if (m < n) {
int s = m; // Variable declared here... scoped to this if
s += recursivesum(m+2, n);
}
}
return s; // No such variable in scope!
}
You could use:
public static int recursivesum(int n, int m) {
int s = 0; // See note below
if (n < m) {
s = n + recursivesum(n+2, m);
} else {
if (m < n) {
s = m + recursivesum(m+2, n);
}
}
return s;
}
We have to give s an explicit initial value, because you currently don't have any code handling the case where n and m are equal. It's not clear what you want to do then.
Another alternative is to return from the if statements, just as you do in iterativesum... although you'll again need to think about what to do if m == n:
public static int recursivesum(int n, int m) {
if (n < m) {
// You don't even need an s variable!
return n + recursivesum(n+2, m);
} else if (m < n) {
// Simplified else { if { ... } } to else if { .... }
return m + recursivesum(m+2, n);
} else {
// What do you want to return here?
}
}
Note that you've got the same problem in iterativesum - the compiler should be complaining at you at the moment that not all paths return a value. What do you expect iterativesum(3, 3) to do?
in recursivesum(int n, int m) method, you have declared s within if condition, but, you tried to access it in else part.
public static int recursivesum(int n, int m){
int s = n; // Now s having method local scope
if (n < m){
s += recursivesum(n+2, m);
} else{
if(m < n){
int s = m;
s += recursivesum(m+2, n);
}
}
return s;
}
In the recursivesum(int n,int m) function the scope of variable s is inside the if and else block. When your returning s it is out of scope.
Try using some IDE's like eclipse. So that you can debug these errors instantly
Try this:
int s;
if (n < m){
s = n;
s += recursivesum(n+2, m);
} else{
if(m < n){
int s = m;
s += recursivesum(m+2, n);
}
}
return s;
You are declaring variable s inside if statement, that is why you get such error. Start from declaration int s outside if statement.
your s is out of scope in recursivesum(int n, int m) method
Declare s outside the if-else block
It's scope problem. You're declaring variable s inside the if statements which is (local definition) of variable.
You need to modify the two methods as follows:
The recursive method will be
public static int recursivesum(int n, int m) {
int s = 0;
if (n < m) {
s = n;
s += recursivesum(n + 2, m);
} else {
if(m < n){
s = m;
s += recursivesum(m + 2, n);
}
}
return s;
}
And the iterative method will be:
public static int iterativesum(int n, int m) {
int s = 0;
if(n < m) {
s = n;
for(int i = n; i <= m; i += 2) {
s += i;
}
} else {
if(m < n) {
s = m;
for(int i = m; i <= n; i += 2) {
s += i;
}
}
}
return s;
}
You have an error in the first method where you define s outside the scope which you return it from. In the second method you return inside the loop.
As others in this thread suggests, use an IDE like Eclipse (https://www.eclipse.org/) or IntelliJ (http://www.jetbrains.com/idea/)
import java.util.Scanner;
public class AssignmentQ7 {
public static int recursivesum(int n, int m) {
int s = n;
if (n < m) {
s += recursivesum(n + 2, m);
}
else {
if (m < n) {
s = m;
s += recursivesum(m + 2, n);
}
}
return s;
}
public static int iterativesum(int n, int m) {
int s = 0;
if (n < m) {
for (int i = n; i <= m; i += 2) {
s += i;
}
}
else if (m < n) {
for (int i = m; i <= n; i += 2) {
s += i;
}
}
return s;
}
public static void main(String args[]) {
int n, m;
Scanner in = new Scanner(System.in);
System.out.println("Enter two numbers: ");
n = in.nextInt();
m = in.nextInt();
while (n % 2 == 0) {
System.out.println("Enter the first number again: ");
n = in.nextInt();
}
while (m % 2 == 0) {
System.out.println("Enter the second number again: ");
m = in.nextInt();
}
System.out.println("The answer of the recursive sum is: " + recursivesum(n, m));
System.out.println("The answer of the iterative sum is: " + iterativesum(n, m));
}
}
Your code must be like this, you dont have to use two for loop.
import java.util.Scanner;
public class AssignmentQ7 {
public static int recursivesum(final int n, final int m) {
final int lower = n < m ? n : m;
final int upper = n > m ? n : m;
final int total = lower;
if (lower >= upper) {
return total;
}
return total + AssignmentQ7.recursivesum(lower + 2, upper);
}
public static int iterativesum(final int n, final int m) {
final int lower = n < m ? n : m;
final int upper = n > m ? n : m;
int total = 0;
for (int num = lower; num <= upper; num = num + 2) {
total += num;
}
return total;
}
public static void main(final String args[]) {
int n, m;
final Scanner in = new Scanner(System.in);
System.out.println("Enter two numbers: ");
n = in.nextInt();
m = in.nextInt();
while (n % 2 == 0) {
System.out.println("Enter the first number again: ");
n = in.nextInt();
}
while (m % 2 == 0) {
System.out.println("Enter the second number again: ");
m = in.nextInt();
}
System.out.println("The answer of the recursive sum is: " + AssignmentQ7.recursivesum(n, m));
System.out.println("The answer of the iterative sum is: " + AssignmentQ7.iterativesum(n, m));
}
}
I've got to ensure that the GCD between 3 numbers is no greater than 1.
Here's the code I have so far for the method:
private int greatestCommonFactor(int a, int b, int c)
{
for(int n = 0; n <= number; n++)
{
if()
}
return 1;
}
the return 1 was already there when I started working on the lab. How can I make sure that the GCD is no more than 1? And return all three integers?
Here's the remainder of the code if it helps in figuring out what needs to be done:
import static java.lang.System.*;
public class Triples
{
private int number;
public Triples()
{
this(0);
}
public Triples(int num)
{
number = num;
}
public void setNum(int num)
{
number = num;
}
private int greatestCommonFactor(int a, int b, int c)
{
for(int n = 0; n <= number; n++)
{
if()
}
return 1;
}
public String toString()
{
String output="";
int max = number;
for(a = 1; a <= max; a++)
{
for(b = a +1; b <= max; b++)
{
for(c = b + 1; c <= max; c++)
{
if(Math.pow(a, 2)+ Math.pow(b, 2)== Math.pow(c, 2))
{
if((a%2==1 && b%2==0)|| (a%2==0 && b%2==1))
}
}
}
}
return output+"\n";
}
}
UPDATE
Here is my new coding for the same lab:
import static java.lang.System.*;
public class Triples
{
private int number;
public Triples()
{
this(0);
}
public Triples(int num)
{
number = num;
}
public void setNum(int num)
{
number = num;
}
private int greatestCommonFactor(int a, int b, int c)
{
for(int n = 0; n <= number; n++)
{
int max = number;
for(a = 1; a <= max; a++)
{
a = n;
for(b = a +1; b <= max; b++)
{
b =n;
for(c = b + 1; c <= max; c++)
{
c = n;
if(Math.pow(a, 2)+ Math.pow(b, 2)== Math.pow(c, 2))
{
if((a%2==1 && b%2==0)|| (a%2==0 && b%2==1))
{
if(a%2<=1 && b%2<=1 && c%2<=1)
{
return 1;
}
}
}
}
}
}
}
return 1;
}
public String toString()
{
String output="";
output = greatestCommonFactor(a, b, c);
return output+"\n";
}
}
You can use Euclid's algorithm to calculate the GCD of a and b. Call the result d. Then the GCD of a, b, and c is the GCD of c and d; for that, you can use Euclid's algorithm again.
Here's a brute-force way if you don't care about efficiency:
private int greatestCommonFactor(int a, int b, int c)
{
limit = Math.min(a, b);
limit = Math.min(limit, c);
for(int n = limit; n >= 2; n--)
{
if ( (a % n == 0) && (b % n == 0) && (c % n == 0) ) {
return n;
}
}
return 1;
}
Explanation:
You can save some work by only checking up to the minimum of (a, b, c). Any number greater than that definitely won't be a GCD of all 3.
You need to start your loop at n = limit instead of n = 0 and count backwards.
As soon as we come across a number that produces zero remainder for (a, b, c), that must be the GCD.
If nothing is found within the loop, GCD defaults to 1.
I am trying some heapsorting in java for fun.
First, I create a max-heap. Then take the first element to variable max, move the last item from unarranged array to the heap top, and then push down.
I tried 21 elements, it works fine 70% of time, I am wondering whether anyone find the problem.
Thanks.
public class HeapSort extends Sort{
public int sort(int arr[]) {
for (int i = 1; i < arr.length; i++) {
// add to heap
int p = i;
int pp = p /2 ;
while (p > 0 && arr[pp] < arr[p]) {
swap(arr, p, pp);
p = pp;
pp = p / 2;
}
}
for (int i = arr.length - 1; i > 0; i--) {
swap(arr, 0, i);
int p = 0;
int child1 = (p << 1) + 1;
int child2 = (p << 1) + 2;
while (child2 < i || child1 < i) {
if (child1 >= i) {
if (arr[p] < arr[child2]) {
swap(arr, p, child2);
p = child2;
} else {
break;
}
} else if (child2 >= i) {
if (arr[p] < arr[child1]) {
swap(arr, p, child1);
p = child1;
} else {
break;
}
} else {
int minIdx = arr[child1] < arr[child2] ? child1 : child2;
int maxIdx = child1 == minIdx ? child2 : child1;
if (arr[p] < arr[maxIdx]) {
swap(arr, p, maxIdx);
p = maxIdx;
} else {
break;
}
}
child1 = (p << 1) + 1;
child2 = (p << 1) + 2;
}
}
return 0;
}
void swap(int arr[], int idx1, int idx2) {
int tmp = arr[idx1]; arr[idx1] = arr[idx2]; arr[idx2] = tmp;
}
public String toString() {
return "HeapSort";
}
}
You're not building the heap correctly in the first step of heap-sort. You need to subtract one before dividing by two on zero based arrays.
public class HeapSort extends Sort{
public int sort(int arr[]) {
for (int i = 1; i < arr.length; i++) { // add to heap
int p = i;
// int pp = p /2 ; <======= Problem!
int pp = (p-1) / 2;
while (p > 0 && arr[pp] < arr[p]) {
swap(arr, p, pp); p = pp;
// pp = p / 2; // <=====Problem!
pp = (p-1) /2;
}