Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm currently learning Java and I stumbled on an exercise I can't finish.
The task is to write a recursive method that takes an array and returns the difference of the greatest and smallest value.
For example {12, 5, 3, 8} should return 5 (8 - 3). It is important to note that it is only allowed to compare values in their right order (result = rightValue - leftValue). For example 12-3 = 9 would not be allowed. Think of it like stock values. You want to find out which time to buy and sell the stocks to make the largest profit.
It was quiet easy to implement this iterative but I have no idea how to do it recursive. Also it is part of the task to solve it by using divide and conquer.
I've used divide and conquer approach here. I believe the trick here is to include middle in both the arrays that we're splitting the main array into.
/* edge cases ignored here */
int findMax(int[] arr, int left, int right){
if(right-left == 1) return (arr[right]-arr[left]);
int middle = left + (right-left)/2;
int max1 = findMax(arr, left, middle);
int max2 = findMax(arr, middle, right);
if(max1 >= 0 && max2 >= 0) return max1+max2;
else return Math.max(max1,max2);
}
Well I don't think recursion is very effective on this. You would probably never do this(other than homework). Something like this would do it:
int findGreatestDifference(Vector<Integer> numbers, int greaterDifference){
if(numbers.size() == 1 ) //return at last element
return greaterDifference;
int newDifference = (numbers.get(0) - numbers.get(1));
if (newDifference > greaterDifference)
greaterDifference = newDifference;
numbers.remove(numbers.size() - 1);
findGreatestDifference(numbers, greaterDifference);
return greaterDifference;
}
first time you call it, pass 0 as the greater difference, and again I don't find this as an effective way to do it. Iteration would be way better for this.
I hope this helps.
Algorithm (this is pretty much a sort task , then the subtraction step is trivial)
1) First sort the arrays (use recursive merge sort for large arrays and recursive insertion for smaller arrays).
Merge sort (https://en.wikipedia.org/wiki/Merge_sort)
Insertion sort (https://en.wikipedia.org/wiki/Insertion_sort)
2) Use the arrays smallest index[0] to get the smallest value & index[array.length-1] to get the largest
3)compute the difference (dont know what you mean by right order?)
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Question :
Given the number k, return the minimum number of Fibonacci numbers whose sum is equal to k, whether a Fibonacci number could be used multiple times.
The Fibonacci numbers are defined as:
F1 = 1
F2 = 1
Fn = Fn-1 + Fn-2 , for n > 2.
It is guaranteed that for the given constraints we can always find such fibonacci numbers that sum k.
Link to question:
https://leetcode.com/problems/find-the-minimum-number-of-fibonacci-numbers-whose-sum-is-k/
Example :
Input: k = 7
Output: 2
Explanation: The Fibonacci numbers are: 1, 1, 2, 3, 5, 8, 13, ...
For k = 7 we can use 2 + 5 = 7.
class Solution {
public int findMinFibonacciNumbers(int count) {
PriorityQueue<Integer> num=new PriorityQueue<>(Collections.reverseOrder());
int i1=1,i2=1;
num.add(i1);
num.add(i2);
int k=count;
int i3=0;
k=k-2;
int res=0;
while(k>=1){
i3=i2+i1;
num.add(i3);
int temp=i2;
i2=i3;
i1=temp;
k--;
}
while(count!=0){
int n=num.poll();
if(n<=count)
{ res++;
count-=n;
}
}
return res;
}
}
It says wrong output for 'input=3'. I generated the fibonacci series and traversed from highest number to find numbers less than or equal to sum. It will be really helpful if somebody helps me.
Thank you in advance.
You can simply use recursion for this problem.
This'll pass through:
class Solution {
public int findMinFibonacciNumbers(int k) {
if (k < 2)
return k;
int first = 1;
int second = 1;
while (second <= k) {
second += first;
first = second - first;
}
return 1 + findMinFibonacciNumbers(k - first);
}
}
References
For additional details, you can see the Discussion Board. There are plenty of accepted solutions with a variety of languages and explanations, efficient algorithms, as well as asymptotic time/space complexity analysis1, 2 in there.
If you are preparing for interviews:
We would want to write bug-free and clean codes based on standards and conventions (e.g., c1, 2, c++1, 2, java1, 2, c#1, 2, python1, javascript1, go1, rust1). Overall, we would like to avoid anything that might become controversial for interviews.
There are also other similar platforms, which you might have to become familiar with, in case you'd be interviewing with specific companies that would use those platforms.
If you are practicing for contests1:
Just code as fast as you can, almost everything else is very trivial.
For easy questions, brute force algorithms usually get accepted. For interviews, brute force is less desired, especially if the question would be an easy level.
For medium and hard questions, about 90% of the time, brute force algorithms fail mostly with Time Limit Exceeded (TLE) and less with Memory Limit Exceeded (MLE) errors.
Contestants are ranked based on an algorithm explained here.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have two large data sets of numeric keys (millions of entries in each) and need to set up a data structure where I can quickly identify key matches between the two sets, allowing for some fixed variation.
So for instance, if there's a value of 356 in one set, I'd like to find any instances of 355, 356 or 357 in the other set. My initial idea was to set up two HashMaps, iterate over the one with the least amount of keys, and then query the larger one over the range (so querying for 355, 356, or 357 in the larger map).
Is there a particular data structure/matching algorithm for numeric values that I should be looking into?
Maybe a java BitSet could be useful in that case. Here's a code sample that uses BitSet of size = 1000000 with a range = 5 to do the check around each values from the first set into the second :
import java.util.*;
import java.lang.*;
import java.io.*;
class CheckRange
{
public static void main (String[] args) throws java.lang.Exception
{
int range = 5;
int maxSize = 1000000;
// Prepare the main BitSet (bs)
BitSet bs = new BitSet(maxSize);
bs.set(357);
bs.set(599001);
bs.set(123456);
// ...
// Prepare the BitSet to check in
BitSet bs2 = new BitSet(maxSize);
bs2.set(5688);
bs2.set(566685);
bs2.set(988562);
// ...
for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
// Compute the ranges, checking the boundaries
int minIndex = Math.max(i - range, 0);
int maxIndex = Math.min(i + range, maxSize);
// Extract the matching subset
BitSet subset = bs2.get(minIndex, maxIndex);
// Print the number of bits set
System.out.println("Number of bit set int bs2 from bs at index " + i + " is " + subset.cardinality());
}
}
}
I'd suggest you start with the Java Set. The "matches between the two sets" that you are seeking sounds a lot like a set intersection.
See API for set operations in Java? and take a look at the description of retainAll.
I will try to summarize a little bit.
Option one - sorted arrays. With binary search, you will be able to find exact value with O(log N) complexity (here and below N is a number of elements in the structure). So, for your operation - log n (search in the first set) + log n (search in the second) + constant (check what you called variation), which is 2 * log N + constant which is O(log N). If data in the collections is changing, you'll have to spend O(log N) to insert it to proper position using similar binary search.
Option two - use Java Set. O(log N) for .contains() call + you'll have to call .contains() for each element of the variation, so we have O(|V| * log N), where |V| is variation size. You also add elements for O(log N).
Decision: I'd choose java set, because there is much fever code to write and you do not need to debug code that search/add element.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I wrote the following code to sort the elements in the array values using a BubbleSort. Is this correct or is there anything missing? My test cases are good, but maybe it's the test cases that are also missing something.
public void sort(ValuePair[] values) {
ValuePair value = null;
for (int i = 0; i < values.length; i++) {
for (int j = 1 + i; j < values.length; j++) {
if (values[i].getValue() > values[j].getValue()) {
value = values[j];
values[j] = values[i];
values[i] = value;
}
}
}
}
Your code is correct in that it will sort the array. However it will always require N*(N-1) passes over the array. This is not
the typical algorithm used to implement
a bubble sort. The typical algorithm uses repeat loop with a test for sorted. This is somewhat more efficient because it
terminates as soon as the array is sorted (consider the case where you start with a sorted array).
Read the Wikepedia article on bubble sort it demonstrates this very well.
A somewhat improved version pseudocode version of Bubble Sort goes something like this:
procedure bubbleSort( A : list of sortable items )
n = length(A)
repeat
swapped = false
for i = 1 to n-1 inclusive do
if A[i-1] > A[i] then
swap(A[i-1], A[i])
swapped = true
end if
end for
n = n - 1
until not swapped
end procedure
The lesson here is that while your algorithm and the Wikepedia algorithm both have the same big O characteristics, a small change
in the way they have been implemented can make a significant difference in their actual performance characteristics.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
My assignment is to make "Yahtzee" game on Java Program.
I am almost done except the Small Straight method. (Cannot figure it out.)
Small Straight is when the dice got 4 straight number. (Ex. 12334, 23345, 34556, and etc.)
Here is my code of isSmallStraight method (This code is not completed!):
public static boolean isSmallStraight(List<Die> dice) {
boolean result = false;
List<Die> copy = new ArrayList<Die>(dice);
Collections.sort(copy);
List<Die> testCase1 = new ArrayList<Die>();
testCase1.add(new Die(1));
testCase1.add(new Die(2));
testCase1.add(new Die(3));
if(copy.containsAll(testCase1)) {
result = true;
System.out.println(result);
}
return result;
}
What I want to do in here is I passed 5 random numbers of dice from the main method (List dice) and put them into the "copy" object.
Since I need to use java.util.List.containsAll() method(requirement), I think I need to make one other object "testCase1" to compare with "copy". (If you have other method to solve this question, it is fine at least you use java.util.containsAll() method.)
However, what I don't know right now is if I use dice.add(new Die(3)), it means the program picks random numbers from 1,2, and 3. (Not die number 3) - Also, it gave me compile-time error.
So, I want to know how I can store dice specific number 1,2,3, and 4 for "testCase1", 2,3,4, and 5 for "testCase2", and 3,4,5, and 6 for "testCase3" and use copy.containsAll(testCase1) becomes true.
Please help me as soon as possible!
PS. Die class is already programmed by my professor. (So, cannot change any in the Die class).
Put the numbers into a TreeSet to get rid of duplicates and get sorting for free.
You have 4 straight dice if:
The set contains exactly 4 numbers
The difference between the largest and the smallest is 3
The method I like to use (for large and small straights as well as all other scoring) is to create a new int array from the int array that holds the dice values. Like this:
int[] numDice = new int[6];
for (int i: diceValues)
numDice[i-1] += 1;
This counts up all your dice and puts the number of each, in order, in a new array. For instance, if the 5 dice you rolled were 3, 4, 3, 1, and 6, your new array would be {1, 0, 2, 1, 0, 1}, and a yahtzee of all 4s would turn into {0, 0, 0, 5, 0, 0}. From this new array it's fairly trivial to determine all of the scores. For straights:
int straightCount = 0;
for (int i: numDice) {
if (i > 0)
straightCount++;
else
straightCount = 0;
if (straightCount > 3)
smallStraight = true;
if (straightCount > 4)
largeStraight = true;
}
If you wanted to you could use this array to easily determine all the valid scores in one short method, and store the booleans in a single array.
I'm practicing recursion using Java and I've hit a problem. I'm trying to make a method which I'm calling "groups" which takes a number of people and how many groups there are and returns the number of different combinations there are of people and groups. Also, the ordering of people in the groups does not matter, nor does the ordering of the groups.
The code I have so far is:
public long groups(int n, int k) {
if(k==1) return 1;
if(k==n) return 1;
else return groups(n-1, k) + groups(n-1, k-1);
}
However it returns the wrong values. The first two lines are the base cases, which say if there is 1 group, then there is only one way to split the people up, makes sense. The other is when there are just as many people as there are groups, in which case theres only one way to split them up, one person into each group. The last statement is where I think I'm having problems, I would think that each time it does a recursive call, one person has to be taken out (n is the number of people, so n-1) and that person can ether join a group (k) or make their own group (k-1).
I'm just having a little trouble figuring out how recursion works and could use a little help.
These are the values I'm expecting:
groups(2,1) = 1
groups(2,2) = 1
groups(3,2) = 3
groups(4,2) = 7
groups(4,3) = 6
groups(5,3) = 25
There is something missing in the implementation of that part
... and that person can ether join a group (k) ...
I think the person can join 'k' groups, so the code must be
public long groups(int n, int k) {
if(k==1) return 1;
if(k==n) return 1;
else return k * groups(n-1, k) + groups(n-1, k-1);
}
(was missing multiplication by k)
There's a much easier (faster) way to compute combinations -- that's the binomial coefficient. While I can understand that your teacher may want you write a recursive function this way to become familiar with recursion, you can use this formula as a check.
In your case, you're reporting the wrong expected values here. What you want is
groups(2,1) = 2
groups(2,2) = 1
groups(3,2) = 3
groups(4,2) = 6
groups(4,3) = 4
groups(5,3) = 10
and the code you've posted is correct if the values above are what it's supposed to return.
(If not, perhaps you can better clarify the problem by explaining more clearly how the problem you're solving differs from the binomial coefficient.)