So I was trying to solve the Max. Product Question and came up with the following recursion :
maxProd(n) = max of [k*(n-k),k*maxProd(n-k),maxProd(k)*(n-k),maxProd(k)*maxProd(n-k)]
However in the second solution given on that link they have skipped the maxProd(k)*maxProd(n-k).
int maxProd(int n)
{
// Base cases
if (n == 0 || n == 1) return 0;
// Make a cut at different places and take the maximum of all
int max_val = 0;
for (int i = 1; i < n; i++)
max_val = max(max_val, i*(n-i), maxProd(n-i)*i);
// Return the maximum of all values
return max_val;
}
Is that still right? If so, how? Wouldn't it give wrong answers when the only way to get Max. Product is recursively split both k and n-k?
The formula you wrote here will also work. But they have a smaller one.
Note that you can get any solution from the original formula, since it checks all possible ways to choose the first cut. So if the first cut has to be i, then i will be checked, and recursively continue to the other parts.
If you use memoization, you'll get the same runtime for both formulas.
Related
I encountered this problem in an interview and I was stuck on the best way to go about it. The question is as follows:
Given a string sequence of words and a string sequence pattern, return true if the sequence of words matches the pattern otherwise false.
Definition of match: A word that is substituted for a variable must always follow that substitution. For example, if "f" is substituted as "monkey" then any time we see another "f" then it must match "monkey" and any time we see "monkey" again it must match "f".
Examples
input: "ant dog cat dog", "a d c d"
output: true
This is true because every variable maps to exactly one word and vice verse.
a -> ant
d -> dog
c -> cat
d -> dog
input: "ant dog cat dog", "a d c e"
output: false
This is false because if we substitute "d" as "dog" then you can not also have "e" be substituted as "dog".
a -> ant
d, e -> dog (Both d and e can't both map to dog so false)
c -> cat
input: "monkey dog eel eel", "e f c c"
output: true
This is true because every variable maps to exactly one word and vice verse.
e -> monkey
f -> dog
c -> eel
Initially, I thought of doing something as follows...
function matchPattern(pattern, stringToMatch) {
var patternBits = pattern.split(" ");
var stringBits = stringToMatch.split(" ");
var dict = {};
if (patternBits.length < 0
|| patternBits.length !== stringBits.length) {
return false;
}
for (var i = 0; i < patternBits.length; i++) {
if (dict.hasOwnProperty(patternBits[i])) {
if (dict[patternBits[i]] !== stringBits[i]) {
return false;
}
} else {
dict[patternBits[i]] = stringBits[i];
}
}
return true;
}
var ifMatches = matchPattern("a e c d", "ant dog cat dog");
console.log("Pattern: " + (ifMatches ? "matches!" : "does not match!"));
However, I realized that this won't work and fails example #2 as it erroneously returns true. One way to deal with this issue is to use a bi-directional dictionary or two dictionaries i.e store both {"a": "ant"} and
{"ant": "a"} and check both scenarios in the if check. However, that seemed like wasted space. Is there a better way to tackle this problem without using regular expressions?
I think a simple choice that is quadratic in the length of the list of words is to verify that every pairing of list indices has the same equality characteristics in the two lists. I'll assume that you get the "words" and "pattern" as lists already and don't need to parse out spaces and whatever -- that ought to be a separate function's responsibility anyway.
function matchesPatternReference(words, pattern) {
if(words.length !== pattern.length) return false;
for(var i = 0; i < words.length; i++)
for(var j = i+1; j < words.length; j++)
if((words[i] === words[j]) !== (pattern[i] === pattern[j]))
return false;
return true;
}
A slightly better approach would be to normalize both lists, then compare the normalized lists for equality. To normalize a list, replace each list element by the number of unique list elements that appear before its first occurrence in the list. This will be linear in the length of the longer list, assuming you believe hash lookups and list appends take constant time. I don't know enough Javascript to know if these are warranted; certainly at worst the idea behind this algorithm can be implemented with suitable data structures in n*log(n) time even without believing that hash lookups are constant time (a somewhat questionable assumption no matter the language).
function normalize(words) {
var next_id = 0;
var ids = {};
var result = [];
for(var i = 0; i < words.length; i++) {
if(!ids.hasOwnProperty(words[i])) {
ids[words[i]] = next_id;
next_id += 1;
}
result.push(ids[words[i]]);
}
return result;
}
function matchesPatternFast(words, pattern) {
return normalize(words) === normalize(pattern);
}
Note: As pointed out in the comments, one should check deep equality of the normalized arrays manually, since === on arrays does an identity comparison in Javascript and does not compare elementwise. See also How to check if two arrays are equal with Javascript?.
Addendum: Below I argue that matchesPatternFast and matchesPatternReference compute the same function -- but use the faulty assumption that === on arrays compares elements pointwise rather than being a pointer comparison.
We can define the following function:
function matchesPatternSlow(words, pattern) {
return matchesPatternReference(normalize(words), normalize(pattern));
}
I observe that normalize(x).length === x.length and normalize(x)[i] === normalize(x)[j] if and only if x[i] === x[j]; therefore matchesPatternSlow computes the same function as matchesPatternReference.
I will now argue that matchesPatternSlow(x,y) === matchesPatternFast(x,y). Certainly if normalize(x) === normalize(y) then we will have this property. matchesPatternFast will manifestly return true. On the other hand, matchesPatternSlow operates by making a number of queries on its two inputs and verifying that these queries always return the same results for both lists: outside the loop, the query is function(x) { return x.length }, and inside the loop, the query is function(x, i, j) { return x[i] === x[j]; }. Since equal objects will respond identically to any query, it follows that all queries on the two normalized lists will align, matchesPatternSlow will also return true.
What if normalize(x) !== normalize(y)? Then matchesPatternFast will manifestly return false. But if they are not equal, then either their lengths do not match -- in which case matchesPatternSlow will also return false from the first check in matchesPatternReference as we hoped -- or else the elements at some index are not equal. Suppose the smallest mismatching index is i. It is a property of normalize that the element at index i will either be equal to an element at index j<i or else it will be one larger than the maximal element from indices 0 through i-1. So we now have four cases to consider:
We have j1<i and j2<i for which normalize(x)[j1] === normalize(x)[i] and normalize(y)[j2] === normalize(y)[i]. But since normalize(x)[i] !== normalize(y)[i] we then know that normalize(x)[j1] !== normalize(y)[i]. So when matchesPatternReference chooses the indices j1 and i, we will find that normalize(x)[j1] === normalize(x)[i] is true and normalize(y)[j1] === normalize(y)[i] is false and immediately return false as we are trying to show.
We have j<i for which normalize(x)[j] === normalize(x)[i] and normalize(y)[i] is not equal to any previous element of normalize(y). Then matchesPatternReference will return false when it chooses the indices j and i, since normalize(x) matches on these indices but normalize(y) doesn't.
We have j<i for which normalize(y)[j] === normalize(y)[i] and normalize(x)[i] is not equal to any previous element of normalize(x). Basically the same as in the previous case.
We have that normalize(x)[i] is one larger than the largest earlier element in normalize(x) and normalize(y)[i] is one larger than the largest earlier element in normalize(y). But since normalize(x) and normalize(y) agree on all previous elements, this means normalize(x)[i] === normalize(y)[i], a contradiction to our assumption that the normalized lists differ at this index.
So in all cases, matchesPatternFast and matchesPatternSlow agree -- hence matchesPatternFast and matchesPatternReference compute the same function.
For this special case, I assume the pattern refers to matching first character. If so, you can simply zip and compare.
# python2.7
words = "ant dog cat dog"
letters = "a d c d"
letters2 = "a d c e"
def match(ws, ls):
ws = ws.split()
ls = ls.split()
return all(w[0] == l for w, l in zip(ws + [[0]], ls + [0]))
print match(words, letters)
print match(words, letters2)
The funny [[0]] and [0] in the end is to ensure that the pattern and the words have the same length.
For example, let's say I want to generate all permutations of two values,each one could be 0 or 1, I would get:
[11,10,01,00]
Note here the first variable varies the slowest, so it stays fixed while the remaining one varies.
In the case of three variables, I would get
[111,110,101,100,011,010,001,000]
I see that there should be a recursive definition for it, but it's not clear enough in my head so that I could express it.
This is not about permutations, but about combinations and you can generate them easily in Haskell:
replicateM 3 "01"
= ["000","001","010","011","100","101","110","111"]
If you need actual integers:
replicateM 3 [0, 1]
= [[0,0,0],[0,0,1],[0,1,0],[0,1,1],
[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
Finally if the values at the various positions are different:
sequence [".x", ".X", "-+"]
= ["..-","..+",".X-",".X+","x.-","x.+","xX-","xX+"]
This too works for integers, of course:
sequence [[0,1], [0,2], [0,4]]
= [[0,0,0],[0,0,4],[0,2,0],[0,2,4],
[1,0,0],[1,0,4],[1,2,0],[1,2,4]]
If you want permuations, as in a list of lists, here's a solution using a list monad.
\n -> mapM (const [0, 1]) [1..n]
ghci> :m +Data.List
ghci> permutations [0,1]
[[0,1],[1,0]]
(Edited based on feedback)
The smallest n-digit binary integer is 000..0 (n times), which is 0.
The largest n-digit binary integer is 111...1 (n times), which is 2^n - 1.
Generate the integers from 0 to 1<<n - 1 and print out the values you have.
Haskell's Int should be safe for <= 28 binary variables.
Hope that helps.
I don't know haskel, but here is a block of psuedo code on how I do permutations.
var positions = [0,0,0];
var max = 1;
done:
while(true){
positions[0]++; //Increment by one
for (var i = 0; i < positions.length; i++) {
if(positions[i] > max){ //If the current position is at max carry over
positions[i] = 0;
if(i+1 >= positions.length){ //no more positions left
break done;
}
positions[i+1]++;
}
}
}
If I have a list of numbers where the numbers increase to a point and then decrease after that point, is there a finite number of guesses independent of the size of the set that I would have to make in order to find that maximum value?
The distance between the values is arbitrary and the number of values on the increasing side can be different than the number of values on the decreasing side.
What would be the best method? Check element 1, then the last element, then the half between? And repeat? Or something more sophisticated?
What would the processing time be for such an algorithm?
You could use a Binary Search comparing two neighboring elements instead of one element to a fixed value. Start at a := 0, b := n, i := (a+b)/2 and compare element(i) to element(i+1). If you notice e(i+1) > e(i), you know the breakpoint is somewhere after i, so set a := i. If e(i) < e(i-1), the opposite is true and you set b := i.
The Complexity would then be O(log n). It would be slightly slower than a regular binary search because you need more comparisons.
You could try a rcursive algorithm simmilar to ordered search, based on the number of elements in your list.
Pseudo code:
List search(int index, List listpart){
if(listpart.length()==1){ // already found
return listpart
}
else if(listpart(index+1)>listpart(i) && listpart(index-1)<listpart(i)){ //search right part
List listpart_tmp = getlistpart(listpart, index, listpart.length())
return search(index+(listpart.length()/4), listpart_tmp
}
else if(listpart(index+1)<listpart(i) && listpart(index-1)>listpart(i)){ //search left part
List listpart_tmp = getlistpart(listpart, 0, index)
return search(index-(listpart.length()/4), listpart_tmp
}
else if(listpart(index+1)<listpart(i) && listpart(index-1)<listpart(i)){ //found
return getlistpart(listpart, index, index)
}
}
The function
getlistpart
is a function that returns a list consisting of the elements in the original list between the given indices.
I'm trying to find the sublist of a list (with at least one positive integer) with the following 2 properties
1. the sum of it's elements is positive
2. it has the maximum length of all the other sub lists with positive sum
I'm only interesting in the length of that list. Kadane's algorithm finds the sublist with maximum sum in O(n) time. Is there an algorithm that can do the same here in O(n)? I've found a solution but it really computes all the sublists and is of course very very slow....
thank you for your time
Calculate the sum of all the numbers say it is n.
If n > 0 then return the full list as the answer.
else
keep trimming the smaller element from both ends and subtract from the sum till the sum turns positive.
Return this as the result.
It is an O(n) algorithm.
Hope it helps
A possible solution is here. You can use Counting sort to sort the array.
After that staring form the maximum element make a sum and check that if adding this element
will retain positive sum of not, if it remain positive add that and increment count move ahead. This might have some bugs for some input,i mean it may not work for all test cases.
but, this is just an idea which may help you as some improvement to this will give you your desired output.
at the end of one traversal count variable will give u result.
example:
array=[12,10,8,5,4,-2,-3,-20,-30] //considered already sorted now
i=0 sum=12 count=1
i=1 sum=22 count=2
i=2 sum=30 count=3
i=3 sum=35 count=4
i=4 sum=39 count=5
i=5 sum=37 count=6
i=6 sum=34 count=7
i=7 sum=14 count=8
i=8 sum=14 count=8 //as now 30 cant be added
so, here count=8 says maximum length sub array of 8 can give you positive sum.
OK, you have almost answered it already. Just modify Kadane's to use length of subsequence rather than the sum of the subsequence. That solves your problem. Here is Kadane's from Wikipedia:
int sequence(int numbers[])
{
// These variables can be added in to track the position of the subarray
size_t begin = 0;
size_t begin_temp = 0;
size_t len_temp = 0;
size_t end = 0;
// Find sequence by looping through
for(size_t i = 1; i < numbers.size(); i++)
{
// calculate max_ending_here
if(max_ending_here < 0)
{
max_ending_here = numbers[i];
begin_temp = i;
}
else
{
max_ending_here += numbers[i];
len_temp += (i - begin_temp);
}
// calculate max_so_far_len
if(len_temp >= max_so_far_len )
{
max_so_far_len = len_temp;
begin = begin_temp;
end = i;
}
}
return max_so_far_len ;
}
Since in your answer u consider sub-lists as consequetive elements , I guess a slight modification in Kadane's Algo will work for you.
Just introduce a variable named max_length_till_now . And update it whenever you found a sub list with length greater than it's present value.
I need to delete the first four rows in a DataSet in my application. Is there a way to do it in the code behind file?
dt.Rows.Cast<System.Data.DataRow>().Take(n).Delete();
Well assuming your DataSet is declared as "ds":
int x = 0;
int n = 4;//n being your number of rows to delete
do
{
ds.Tables[0].Rows[x].Delete();
x++;
} while (x < n);
Edit: Updated the "error" in my logic... >.< I was saying something like x = n, which won't delete the first four rows in a dataset.
mydatatable = mydataset.Tables[0].Rows
.Cast<System.Data.DataRow>()
.OrderBy(x => x["Numbers"]).Skip(1).CopyToDataTable();
skip() function will skip that row and copy remaining rows to target datatable , so we can use it as delete