Fenwick Tree Java - java

I tried to implement the Fenwick Tree in Java, but I am not getting the desired result.
Here is my code:
import java.io.*;
import java.util.*;
import java.math.*;
class fenwick1 {
public static int N;
public static long[] a;
public static void main(String[] args)throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
a = new long[N];
String[] str = br.readLine().split(" ");
for (int i = 0; i < N; i++) {
a[i] = Long.parseLong(str[i]);
}
increment(2, 10);
System.out.println(a[2]);
System.out.println(query(4));
}
public static void increment(int at, int by) {
while (at < a.length) {
a[at] += by;
at |= (at + 1);
}
}
public static int query(int at) {
int res = 0;
while (at >= 0) {
res += a[at];
at = (at & (at + 1)) - 1;
}
return res;
}
}
When I give input:
10
1 2 3 4 5 6 7 8 9 10
I get:
13
19
So the increment function works fine. But query(4) should give the cumulative sum up to index 4 i.e.
(1 + 2 + 13 + 4 + 5) = 25

You do not initialize it properly.
Instead of:
for (int i = 0; i < N; i++) {
a[i] = Long.parseLong(str[i]);
}
It should be:
for (int i = 0; i < N; i++) {
increment(i, (int)Long.parseLong(str[i]));
}
because a[i] should store a cumulative sum, not a single element.
If you want to store the initial array elements too, you can just create one more array:
long[] initA = new long[N];
for (int i = 0; i < N; i++) {
initA[i] = Long.parseLong(str[i]);
increment(i, (int)initA[i]);
}

Related

Perfect Numbers in an ArrayList

This is an exercise.
A perfect number is a number whose sum of divisors without itself is equal to that number
6 is a perfect number because its divisors are: 1,2,3,6 and 1 + 2 + 3 = 6
28 is a perfect number because its divisors are: 1,2,4,7,28 and 1 + 2 + 4 + 7 = 28
Task: write the body of findNPerfectNumbers, which will find n prime perfect numbers and return them as a list
I must use this program:
import java.util.ArrayList;
public class Exercise {
public static ArrayList<Integer> findNPerfectNumbers(int n)
{
return new ArrayList<>();
}
public static void main(String[] args)
{
System.out.println(findNPerfectNumbers(4));
}
}
I create this code to resolve this problem, but I have a problem to return an ArrayList. I don't know how. It should look like this example: 6 = 1,2,3,6 ///// 28 = 1, 2, 4, 7
My idea:
import java.util.ArrayList;
public class Main
{
public static ArrayList<Integer> findNPerfectNumbers(int n)
{
int sum = 0;
ArrayList<Integer> perfectList = new ArrayList<>();
ArrayList<Integer> factorList = new ArrayList<>();
for (int i = 6; i < n; i++)
{
factorList.clear();
for (int j = 1; j <= i / 2; j++)
{
if (i % j == 0)
{
factorList.add(j);
}
}
sum = 0;
for (int h = 0; h < factorList.size(); h++)
{
sum = sum + factorList.get(h);
}
if (sum == i)
{
perfectList.add(i);
}
}
return perfectList;
}
public static void main(String[] args)
{
System.out.println(findNPerfectNumbers(28));
}
}
Anyone have an idea?
The question is as simple as to have the findNPerfectNumbers function return the first N perfect numbers.
The main part for the exercise is probably to do this as efficiently as possible. For example limiting divider check by half like you do in for (int j = 1; j <= i / 2; j++) is one of many options.
The reason your function doesn't return anything though is because your outer for loop is incorrect with the given input of 4 what you'r doing is for (int i = 6; i < 4; i++) which doesn't do any loops because 4 is smaller than 6.
what you probably intended to do issomething like for (int i = 6; perfectList.size() < n; i++) which would loop aslong as you have fewer than N perfect numbers.
example working code:
import java.util.ArrayList;
public class Exercise {
public static ArrayList<Integer> findNPerfectNumbers(int n) {
int sum = 0;
ArrayList<Integer> perfectList = new ArrayList<>();
for (int i = 6; perfectList.size() < n; i++) {
ArrayList<Integer> factorList = new ArrayList<>();
for (int j = 1; j <= i / 2; j++) {
if (i % j == 0) {
factorList.add(j);
}
}
sum = 0;
for (Integer factor : factorList) {
sum += factor;
}
if (sum == i) {
System.out.println("Found perfect number " + i + " with factors " + factorList);
perfectList.add(i);
}
}
return perfectList;
}
public static void main(String[] args) {
System.out.println(findNPerfectNumbers(4));
}
}
If number is less than 10^1500 you can use Euclid's method
public static List<Long> findPerfect(int n){
List<Long> perfectList=new ArrayList<>();
int x=0;
long sum=0;
long last;
while(perfectList.size()!=n){
last= (long) Math.pow(2,x);
sum+=last;
if(isPrime(sum))
perfectList.add(sum*last);
x++;
}
return perfectList;
}
public static boolean isPrime(long x){
if(x==1)
return false;
for (int i = 2; i <= Math.sqrt(x); i++) {
if(x%i==0)
return false;
}
return true;
}

Is there a test case scenario in which my program will fail?

Problem : You have L, a list containing some digits (0 to 9). Write a function solution(L) which finds the largest number that can be made from some or all of these digits and is divisible by 3. If it is not possible to make such a number, return 0 as the solution. L will contain anywhere from 1 to 9 digits. The same digit may appear multiple times in the list, but each element in the list may only be used once.
Test Cases :
Input:
Solution.solution({3, 1, 4, 1})
Output: 4311
Input:
Solution.solution({3, 1, 4, 1, 5, 9})
Output: 94311
My Program :
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.stream.IntStream;
public class Solution {
static ArrayList<Integer> al = new ArrayList<Integer>();
static ArrayList<Integer> largest = new ArrayList<Integer>();
static int o = 1;
static int po = 0;
static void combinations(String[] digits, String[] data, int start, int end, int index, int r)
{
if (index == r)
{
String temp = "0";
for (int j = 0; j < r; j++)
{
temp = temp + data[j];
// System.out.print(data[j]);
}
Integer d = Integer.parseInt(temp);
al.add(d);
// System.out.println(al);
}
for (int i = start; i <= end && ((end - i + 1) >= (r - index)); i++)
{
data[index] = digits[i];
combinations(digits, data, i + 1, end, index + 1, r);
}
}
static void printCombinations(String[] sequence, int N)
{
String[] data = new String[N];
for (int r = 0; r < sequence.length; r++)
combinations(sequence, data, 0, N - 1, 0, r);
}
static String[] convert(int[] x)
{
String c[] = new String[x.length];
for(int i=0; i < x.length; i++)
{
Integer k = x[i];
if(k==0)
{
o = o * 10;
continue;
}
c[i] = k.toString();
}
// System.out.println(o);
c = Arrays.stream(c).filter(s -> (s != null && s.length() > 0)).toArray(String[]::new);
po = c.length;
// System.out.println("Come"+ Arrays.asList(c));
return c;
}
public static int solution(int[] l) {
if(l.length==0)
return 0;
if(IntStream.of(l).sum()%3==0)
{
String x = "";
Arrays.sort(l);
for (int i = l.length - 1; i >= 0; i--) {
x = x + l[i];
}
return Integer.parseInt(x);
}
printCombinations(convert(l),po);
al.sort(Comparator.reverseOrder());
al.remove(al.size()-1);
al.removeIf( num -> num%3!=0);
if(al.isEmpty())
return 0;
for(int i=0; i< al.size(); i++)
{
Integer n = al.get(i);
printMaxNum(n);
}
// System.out.println(al);
// System.out.println(largest);
return largest.get(0)*o;
}
static void printMaxNum(int num)
{
// hashed array to store count of digits
int count[] = new int[10];
// Converting given number to string
String str = Integer.toString(num);
// Updating the count array
for(int i=0; i < str.length(); i++)
count[str.charAt(i)-'0']++;
// result is to store the final number
int result = 0, multiplier = 1;
// Traversing the count array
// to calculate the maximum number
for (int i = 0; i <= 9; i++)
{
while (count[i] > 0)
{
result = result + (i * multiplier);
count[i]--;
multiplier = multiplier * 10;
}
}
// return the result
largest.add(result);
}
public static void main(String[] args) {
System.out.println(solution(new int[]{9,8,2,3}));
}
}
My Code passes both given test cases and 3 other hidden test cases except one. I tried all possible input combinations but couldn't get to the exact failure. The return type by default is given as int and therefore they would not pass values which give output that does not fit in int. Any other scenario where my code fails?

timings problems in hackerrank in “Beautiful Triplets” question

I am solving the "Beautiful Triplets" problem may be my logic is correct but it is showing the timings problems The Question is given below in image.My solution for same is given below. It contains only given function beautifulTriplets(int d, int[] arr) which is returning integer and accepting two values one is d and second is array of integer. Some cases are runnning but some are showing timings error.
The question is
Question
The solutions for same is
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;
public class Solution {
// Complete the beautifulTriplets function below.
static int beautifulTriplets(int d, int[] arr) {
int i,j,k,beautifulTripletsCount=0;
for(i=0;i<(arr.length-2);i++)
{
for(j=i+1;j<(arr.length-1);j++)
{
for(k=j+1;k<(arr.length);k++)
{
if(i<j&& j<k)
{
int j_i_Difference=arr[j]-arr[i];
int k_j_Difference=arr[k]-arr[j];
if(j_i_Difference==k_j_Difference && k_j_Difference==d)
{
beautifulTripletsCount++;
}
}
}
}
}
return beautifulTripletsCount;
}
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
String[] nd = scanner.nextLine().split(" ");
int n = Integer.parseInt(nd[0]);
int d = Integer.parseInt(nd[1]);
int[] arr = new int[n];
String[] arrItems = scanner.nextLine().split(" ");
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
for (int i = 0; i < n; i++) {
int arrItem = Integer.parseInt(arrItems[i]);
arr[i] = arrItem;
}
int result = beautifulTriplets(d, arr);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
bufferedWriter.close();
scanner.close();
}
}
Your solution of 3 nested loops has a running time of O(n^3).
You can improve it to O(n^2) as follows:
Let i go from 1 to arr.length - 2. Find the number of beautiful triplets in which arr[i] is the middle element:
Iterate from i-1 down to 0 to count how many elements are equal to arr[i] - d
Iterate from i+1 up to arr.length - 1 to count how many elements are equal to arr[i] + d
Multiply the two numbers you found in the previous two steps and add the product to the total number of beautiful triplets.
This will give you a total running time of O(n^2) even if the input array is not sorted.
If the input array is sorted, you can do better, since steps 2. and 3. can be done with binary search, and therefore take O(logn) instead of O(n). This will give you a total running time of O(nlogn).
The version for general (unsorted) arrays:
int result = 0;
for (int i = 1; i < arr.length - 1; i++) {
int first = 0;
int third = 0;
for (int j = i - 1; j >= 0; j--) {
if (arr[i] - arr[j] == k) {
first++;
}
}
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] - arr[i] == k) {
third++;
}
}
result += first * third;
}
My solution to improve timing was to make one loop and find in the array the indexes j and k base on adding d to the value at position i and j. I used binarySearch implementation from java.
int count = 0;
Arrays.sort(arr);
for (int i = 0; i < arr.length; i++) {
int j = Arrays.binarySearch(arr, arr[i] + d);
if (j > 0) {
int k =Arrays.binarySearch(arr, arr[j] + d);
if (k > 0) {
count++;
}
}
}
return count;
Here is my accepted solution for BeautifulTriplets on HackerRank.
import java.util.List;
public class BeautifulTriplets {
public int beautifulTriplets(int d, List<Integer> arr) {
int size = arr.size();
int beautifulTripletsCount = 0;
for (int i = 0; i < size - 2; i++) {
for (int j = i + 1; j < size - 1; j++) {
if (arr.get(j) - arr.get(i) == d) {
for (int k = j + 1; k < size; k++) {
if (arr.get(k) - arr.get(j) == d) {
beautifulTripletsCount++;
}
}
}
}
}
return beautifulTripletsCount;
}
}
And here is the test case with 2 sample inputs.
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
class BeautifulTripletsTest {
#Test
void shouldReturnCountOfBeautifulTriplets() {
BeautifulTriplets beautifulTriplets = new BeautifulTriplets();
Assertions.assertEquals(3, beautifulTriplets.beautifulTriplets(3, Arrays.asList(1, 2, 4, 5, 7, 8, 10)));
Assertions.assertEquals(2, beautifulTriplets.beautifulTriplets(3, Arrays.asList(1, 6, 7, 7, 8, 10, 12, 13, 14, 19)));
}
}

Printing a particular value from an array

How can I print the value of a Fibonacci function for any particular index, say n, where n is the provided argument value?
1 import java.util.Arrays;
2
3 public class Fibonacci {
4
5 public static void main(String[] args) {
6 int n = Integer.parseInt(args[0]);
7 if(n<3){
8 return;
9 }else{
10 int[] f = new int[n];
11 f[0] = 1;
12 f[1] = 1;
13 int i= 0;
14 for(i=2; i<f.length; i++){
15 f[i]= f[i-1]+ f[i-2];
16 }
17 System.out.println(f[i]);
18 }
19
20 }
21
22 }
Your code is basically fine, but I tweaked a few things in my response:
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
if (n < 0) {
System.out.println("Cannot computer Fib() of a negative number.");
return(0);
} else if (n < 3) {
System.out.println("Fib[" + n + "] = 1");
} else {
int[] f = new int[n];
f[0] = 1;
f[1] = 1;
for(int i=2; i < f.length; ++i) {
f[i] = f[i-1]+ f[i-2];
}
System.out.println("Fib[" + n + "] = " + f[n - 1]);
}
}
The problem you have, I believe, is System.out.println(f[i]);
At this spot, i will be equals to length of f[]. If you use i as index, it will be out of bound.
If you are going to print the last value, it should be System.out.println(f[i-1]);
You are printing f[i] which will give you ArrayIndexOutOfBoundsException since at that time value of i crosses the boundary of array f.
A simple workaround would be to print array by taking a separate variable like this :
int n = Integer.parseInt(args[0]);
if(n<3){
return;
}else{
int[] f = new int[n];
f[0] = 1;
f[1] = 1;
int i= 0;
for(i=2; i<f.length; i++){
f[i]= f[i-1]+ f[i-2];
}
for (int j=0;j<n;j++){
System.out.println(f[j]);
}
}
If you want to print any particular index then you can make one boundary check before printing:
int index=5;
if(index<f.length){
System.out.println(f[index]);
}
I think It's better to have Fibonachi in the recursive way:
public int fib(int n) {
if (n < 2) {
return n;
}
else {
return fib(n-1)+fib(n-2);
}
System.out.println(n);
}

Print all the combinations of elements in matrix of size m * n

Print all the combinations of elements in matrix of size m * n
Sample Example:
1 3 5
2 6 7
Expected Output:
1 , 3 , 5
1 , 3 , 7
1 , 6 , 5
1 , 6 , 7
2 , 3 , 5
2 , 3 , 7
2 , 6 , 5
2 , 6 , 7
Rules:
Every combination starts from left of matrix and proceeds towards right. It may switch rows though.
Every combination should have number of elements equal to number of columns.
A combination can't have an element from the same column present twice.
Number of columns and rows could vary. So solution has to be generic.
import java.util.Scanner;
class Combination {
public static void main(String args[]) {
int row, col, i, j;
Scanner in = new Scanner(System.in);
System.out.println("Enter the number of rows and columns of matrix:\n");
row = in.nextInt();
col = in.nextInt();
int first[][] = new int[row][col];
System.out.println("Enter the elements if matric m*n:\n");
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
first[i][j] = in.nextInt();
}
}
System.out.println("Matrix:\n");
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
System.out.print(first[i][j] + "\t");
}
System.out.println();
}
// Final Logic from here...
System.out.println("\nOut Matrix:\n");
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
System.out.println(first[i][0] + "," + first[j][1] + ","
+ first[k][2]+"\n");
}
}
}
/* while (i < 2) {
j = 0;
while (j < 2) {
k = 0;
while (k < 2) {
System.out.println(first[i][0] + "," + first[j][1] + ","
+ first[k][2]);
k++;
}
j++;
}
i++;
}*/
in.close();
}
}
Works good for specific input but not able to do it dynamic....Need Help..
Thanks in Advance......
You could use recursion as follows:
...
// Final Logic from here...
System.out.println("\nOut Matrix:\n");
int[] outputRow = new int[col];
print(0, row, col, first, outputRow);
}
private static void print(int j, int row, int col, int[][] first, int[] outputRow) {
for (int i = 0; i < row; i++) {
outputRow[j] = first[i][j];
// recursively continue to populate outputRow until we reach the last column (j == col -1)
if (j < col - 1) {
print(j + 1, row, col, first, outputRow);
}
// we have reached the last column (j == col -1) so now we could print current permutation
if (j == col - 1) {
for (int k = 0; k < col; k++) {
System.out.print(" " + outputRow[k]);
}
System.out.println();
}
}
}
Here we process one column per recursion call starting with j==0.
outputRow stores the current permutation and is updated recursively.
When we recursively reach the last column then it's time to print the current permutation.
This is a possible approach
void printCombos(){
visit(0,-1,"");
}
void visit(int r,int c,String s){
if(c!=a[0].length-1)
for(int i=0;i<a.length;i++)
visit(i,c+1,s+" - "+a[i][c+1]);
else
System.out.println(s);
}
considering the matrix as a tree to deep-visit. Given an imaginary root * these are the edges (*,1) - (*,2) - (1,3) - (1,6) - (2,3) - (2,6) and so on
* --- 1 -- 3 -- 5
\ \/ \/
\ /\ /\
\ 2 -- 6 -- 7
with 5 and 7 being the leaves.
First create one more method :
private static void increasePointerArray(int[] poinerArray, int row)
{
for (int i = poinerArray.length-1; i >= 0; i--) {
if(poinerArray[i] == row-1) {
continue;
}
else {
poinerArray[i] = poinerArray[i] +1;
for (int j = i+1; j < poinerArray.length; j++) {
poinerArray[j] = 0;
}
break;
}
}
}
Now in final logic section put below code :
int[] poinerArray = new int[col];
int[] MaxArray = new int[col];
List<int[]> resultList = new ArrayList<int[]>();
Arrays.fill(poinerArray, 0);
Arrays.fill(MaxArray, row-1);
while(!Arrays.equals(poinerArray, MaxArray)) {
resultList.add(poinerArray.clone());
increasePointerArray(poinerArray, row);
}
resultList.add(poinerArray.clone());
System.out.println("Printing desired result : ");
for (int[] ks : resultList) {
StringBuffer sb = new StringBuffer();
for (j = 0; j < col; j++) {
sb.append(first[ks[j]][j]+"\t");
}
System.out.println(sb.toString());
sb = null;
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class Permutations{
public static String strings="";
public static ArrayList<String> out=new ArrayList<String>();
public static void gen(ArrayList<ArrayList<String>> x,int index){
for(int i=0;i<x.size();i++){
if(i>0){
String[] parts=strings.split(",");
strings="";
for(int k=0;k<parts.length;k++){
if(k==index)
break;
strings=strings+parts[k]+",";
}
}
if(index==x.get(0).size()-1){
strings=strings+(x.get(i).get(index));
out.add(strings);
}
else
strings=strings+(x.get(i).get(index))+",";
if(index+1<=x.get(0).size()-1)
gen(x,index+1);
}
}
public static void main(String[] args) throws IOException{
ArrayList<ArrayList<String>> x=new ArrayList<ArrayList<String>>();
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line;
while(true){
line=br.readLine();
if(line.contentEquals("")) break;
String[] parts=line.split(" ");
x.add(new ArrayList<String>());
for(int i=0;i<parts.length;i++){
x.get(x.size()-1).add(parts[i]);
}
}
gen(x,0);
for(int i=0;i<out.size();i++){
System.out.println(out.get(i));
}
}
}
This code is works. Its very generic and quite simple to understand. I did column wise permutations on the 2D Array.

Categories