Memoization is giving me wrong answers. Please can some one help me out here. Without memorization, I am getting the right answers as in function targetBestR, but in the memoized function targetBestM, I am getting the wrong values being stored in the array list for the respective keys.
import java.util.ArrayList;
import java.util.HashMap;
public class TargetSumBest {
public static ArrayList<Integer> targetBestR(int n, int arr[]){
if(n==0) return new ArrayList<Integer>();
if(n<0) return null;
ArrayList<Integer> shortestCombo=null;
for(int i=0;i<arr.length;i++) {
//System.out.println(i);
//System.out.println(arr[i]);
int rem=n-arr[i];
//System.out.println(n+"-"+i+"="+rem);
ArrayList<Integer> tar=targetBestR(rem, arr);
if(tar!=null) {
tar.add(arr[i]);
if(shortestCombo==null||tar.size()<shortestCombo.size()) {
shortestCombo=tar;
}
}
}
//System.out.println(n+"value"+shortestCombo);
return shortestCombo;
}
public static ArrayList<Integer> targetBestM(int n, int arr[], HashMap<Integer, ArrayList<Integer>> memo){
if(n==0) return new ArrayList<Integer>();
if(n<0) return null;
if(memo.containsKey(n)) return memo.get(n);
ArrayList<Integer> shortestCombo=null;
for(int i=0;i<arr.length;i++) {
//System.out.println(i);
//System.out.println(arr[i]);
int rem=n-arr[i];
//System.out.println(n+"-"+i+"="+rem);
ArrayList<Integer> tar=targetBestM(rem, arr,memo);
if(tar!=null) {
tar.add(arr[i]);
if(shortestCombo==null||tar.size()<shortestCombo.size()) {
shortestCombo=tar;
}
}
}
//System.out.println(n+"value"+shortestCombo);
memo.put(n, shortestCombo);
return shortestCombo;
}
public static void main(String[] args) {
int n=8; int arr[]= {1,4,2};
System.out.println(targetBestM(n, arr, new HashMap<Integer, ArrayList<Integer>>()));
System.out.println(targetBestR(n, arr));
}
}//error
Was able to find the problem. The array passed into the HashMap keeps getting used and added to. Was able to fix it by creating new ArrayLists when reading and writing from the HashMap.
when reading...
if (memo.containsKey(n)) {
System.out.println(indent + n + " memo.get(n) = " + memo.get(n));
return new ArrayList<>(memo.get(n));
}
when writing...
memo.put(n, new ArrayList<>(shortestCombo));
Related
The question is to find three triplets which comes to zero sum.
Link: https://www.codingninjas.com/codestudio/guided-paths/data-structures-algorithms/content/118509/offering/1376555?leftPanelTab=0
My Code:
import java.util.* ;
import java.io.*;
import java.util.ArrayList;
public class Solution {
public static ArrayList<ArrayList<Integer>> findTriplets(ArrayList<Integer> arr, int n) {
// Write your code here.
Collections.sort(arr);
ArrayList<ArrayList<Integer>> anslist=new ArrayList<ArrayList<Integer>> ();
for(int i=0;i<n-2;i++)
{
ArrayList<Integer> ans= twosum(arr,-arr.get(i),i+1,n);
if(ans.size()==2)
{
ans.add(arr.get(i));
}
anslist.add(ans);
}
return anslist;
}
public static ArrayList<Integer> twosum(ArrayList<Integer> arr, int target, int i,int n)
{
int j=n-1;
while(i<j && i<arr.size() && j<arr.size())
{
if((arr.get(i)+arr.get(j))<target)
i++;
else if((arr.get(i)+arr.get(j))>target)
j--;
else
{
ArrayList<Integer> finalist = new ArrayList<Integer>(Arrays.asList(arr.get(i), arr.get(j)));
return finalist;
}
}
return new ArrayList<Integer>();
}
}
I tried to play with the arraylist indices and if-else checkers but nothing worked!I am unable to understand where I am going out of bounds! Plz help me out. I know that there is a hashmap based approach bUt I wanna do it this way..
Below is the problem statement from hackerrank
Mark and Jane are very happy after having their first child. Their son loves toys, so Mark wants to buy some. There are a number of different toys lying in front of him, tagged with their prices. Mark has only a certain amount to spend, and he wants to maximize the number of toys he buys with this money.
Given a list of prices and an amount to spend, what is the maximum number of toys Mark can buy? For example, if prices = [1,2,3,4] and Mark has k=7 to spend, he can buy items [1,2,3] for 6, or [3,4] for 7 units of currency. He would choose the first group of 3 items.
Below is code I wrote for this problem which involves backtracking technique
import java.util.ArrayList;
import java.util.Collections;
public class MarkAndToys {
static ArrayList<Integer> possibleSolutions = new ArrayList<>();
static boolean findSolution(int[] prices,int amount,int left,int length,int items){
// Base case: if whole array was iterated and amount is >=0 then we got a solution
if(left >= length){
if(amount>=0){
possibleSolutions.add(items);
return true;
}
return false;
}
// Key idea: prices[left] is chosen or it is not.
// Deal with prices[left], letting recursion
// deal with all the rest of the array.
// Recursive call trying the case that prices[left] is chosen --
// subtract it from amount in the call.
if (findSolution(prices,amount-prices[left],left+1,length,items+1)) return true;
// Recursive call trying the case that prices[left] is not chosen.
if (findSolution(prices,amount,left+1,length,items)) return true;
// If neither of the above worked, it's not possible.
return false;
}
// Complete the maximumToys function below.
static int maximumToys(int[] prices, int k) {
if(findSolution(prices,k,0,prices.length,0)){
//if solutions are found then return maximum of them
return Collections.max(possibleSolutions);
}
return 0;
}
public static void main(String[] args) {
System.out.println(maximumToys(new int[]{1,12,5,111,200,1000,10}, 50));
}
}
This seems to be working fine:
// Complete the maximumToys function below.
static int maximumToys(int[] prices, int k) {
Arrays.sort(prices);
int sum = 0;
int index = 0;
for(int i = 0; i < prices.length; i++) {
sum+=prices[i];
index = i;
if(sum > k) {
break;
}
}
return index;
}
package Scanarios;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class Toys {
public static void main(String[] args) {
Toys t=new Toys();
int[] a = {3,6,2,1,4,5};
int q=1;
int n=6;
ArrayList<Integer> queries[]=new ArrayList[n];
ArrayList<Integer> result=new ArrayList();
for (int i = 0; i < n; i++) {
queries[i] = new ArrayList<Integer>();
}
queries[0].add(10);
queries[0].add(2);
queries[0].add(2);
queries[0].add(5);
result=t.maximumToys(n,a,q,queries);
System.out.println(result);
}
public ArrayList<Integer> maximumToys(int n, int a[], int q, ArrayList<Integer> queries[]) {
ArrayList<Integer> arrlist=new ArrayList();
for(int z=0;z<q;z++) {
int[] arr=queries[z].stream().mapToInt(i -> i).toArray();
int cost=arr[0];
int k=arr[1];
int count=0;
int[] proxyarr=new int[n-1];
proxyarr =removeBrokenPrice(a,arr,k);
Arrays.sort(proxyarr);
for(int i=0;i< proxyarr.length;i++) {
cost -=proxyarr[i];
if(cost > 0) {
count++; }else {
break;
}
}
arrlist.add(count);
}
return arrlist;
}
int[] removeBrokenPrice (int a[],int b[],int k){
int count=0;
for(int i=k;i <= b.length-1;i++) {
for(int j=0;j<a.length;j++) {
if(j==b[i]-1) {
a[j]=-1;
count++;
}
}
}
int[] proxyarr=new int[a.length-count];
for(int i=0,j=0;i< a.length;i++)
{
if(a[i]==-1) {
continue;
}else {
proxyarr[j++]=a[i];
}
}
return proxyarr;
}
}
How can I write a test to print this result?
package leetcode_one_twenty;
import java.util.HashMap; // HashMap package
public class Two_Sum {
public int[] twoSum(int[] numbers, int target) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < numbers.length; i++) {
if (map.get(numbers[i]) != null) {
int[] result = {map.get(numbers[i]) + 1, i + 1};
return result;
}
map.put(target - numbers[i], i);
}
int[] result = {};
return result;
}
public static void main(String[] args) {
// How can I write a test to print this result? THX!
}
}
Make your twoSum method static, and call it with values from your main method:
int[] myArray = {1,2,3};
int target = 5;
System.out.println(Arrays.toString(twoSum(myArray, target)));
I'm not really sure what are you exactly trying to do. Why not try System.out.println() and toString()?
I'm struggling with a really simple problem in java. I've implemented quicksort in java that works on arraylists and can take any value. The problem is that it works only for an arraylist lower than about 8000 size.
Can anyone tell me what's wrong with my program? I think it might be connected with recursion depth limit but i'm not sure (because sometimes it works for larger sizes and sometimes not). How can I improve my quicksort implementation so it will work for much larger size of Arraylist like 100000?
import java.util.ArrayList;
import java.util.Random;
public class QuickSort {
Random gener;
int temporary,genertype,NInts,flag;
ArrayList<Integer> mylist;
public QuickSort(int type,int ilosc){
gener = new Random();
mylist= new ArrayList<>();
this.genertype=type;
this.NInts=ilosc;
}
void generate(){
if(genertype==0){
for(int i=0;i<NInts;i++){
mylist.add(gener.nextInt(100000));
}
}else {
for(int i=0;i<NInts;i++){
mylist.add(NInts-i);
}
}
}
int count1(ArrayList<Integer> list,int counter1,int counter2){
while(list.get(0)<list.get(counter1)){
if(counter1==counter2){
flag=1;
return counter1;
}
counter1++;
}
flag=0;
return counter1;
}
int count2(ArrayList<Integer> list,int counter1,int counter2){
while(list.get(0)>list.get(counter2)){
if(counter1==counter2){
flag=1;
return counter2;
}
counter2--;
}
flag=0;
return counter2;
}
public ArrayList<Integer> sorting(ArrayList<Integer> list) {
ArrayList<Integer> left = new ArrayList<Integer>();
ArrayList<Integer> right = new ArrayList<Integer>();
int counter1,counter2;
if (list.size() == 1) {
return list;
}else {
counter1=1;
counter2=list.size()-1;
while(counter1!=counter2) {
counter1=count1(list,counter1,counter2);
if(flag==1)
break;
counter2=count2(list,counter1,counter2);
if(flag==1)
break;
temporary = list.get(counter1);
list.set(counter1, list.get(counter2));
list.set(counter2, temporary);
}
for (int i = 0; i < counter1; i++) {
left.add(list.get(i));
}
for (int i = counter1; i < list.size(); i++) {
right.add(list.get(i));
}
left = sorting(left);
right = sorting(right);
list=merge(left, right);
}
return list;
}
ArrayList<Integer> merge(ArrayList<Integer> left, ArrayList<Integer> right) {
if(left.get(0)>right.get(right.size()-1)){
right.addAll(left);
return right;
}
else{
left.addAll(right);
return left;
}
}
void printing(){
for(int k=0;k<NInts;k++){
System.out.print(" "+mylist.get(k));
}
}
public static void main(String[] args){
QuickSort instance = new QuickSort(1,1000);
instance.generate();
instance.mylist=instance.sorting(instance.mylist);
instance.printing();
}
}
Ps.If you see anything wrong in my code, let me know so I can improve it :)
There could be many reasons why your code could not run for large number of inputs. Mostly it could be because the Heap Size capacity specified for your application is overflown. This can be resolved by increasing Heap Size of your application (check out this stackoverflow link on how to increase the heap size of your application)
I wrote the following code for Pascal's triangle on https://leetcode.com/ and I got the error as follows:
Line 10: error: incompatible types: int cannot be converted to
List<List<Integer>>.
public class Solution {
public List<List<Integer>> generate(int numRows) {
List list;
int temp;
for(int i=0;i<numRows;i++) {
temp = (int) Math.pow(11,i);
list.add(Arrays.asList(temp));
}
return temp;
}
public static void main(String s[]) {
Solution solution = new Solution();
java.util.Scanner scan = new java.util.Scanner();
System.out.println("Enter the no.of Rows");
int numRows = scan.nextInt();
solution.generate(numRows);
}
}
Help me to find the solution.
You have almost right answer. Just few mistypes. Here is good one:
import java.util.ArrayList;
import java.util.List;
public class Solution {
public List<Integer> generate(int numRows) {
List<Integer> list=new ArrayList<Integer>();
int temp;
for (int i = 0; i < numRows; i++) {
temp = (int) Math.pow(11, i);
list.add(temp);
}
return list;
}
public static void main(String s[]) {
Solution solution = new Solution();
java.util.Scanner scan = new java.util.Scanner(System.in);
System.out.println("Enter the no.of Rows");
int numRows = scan.nextInt();
Object answer=solution.generate(numRows);
System.out.println(answer);
}
}
Your method is defined as returning a List<List<Integer>> (a list of lists of integers) but you are trying to return an integer.
You have created the List in the method, so you should return that, and not the integer temp.
public List<Integer> generate(int numRows) {
List list;
int temp;
for(int i=0;i<numRows;i++) {
temp = (int) Math.pow(11,i);
list.add(Arrays.asList(temp));
}
return list;
Why are returning int value for List return type. please change it to list. It will compile properly.