I have tried multiple variations of this, but none of them seem to work. Any ideas?
int[] array = new int[n];
for(int i = 0; i < array[0]; i++){
for(int j = 0; j < array[1]; j++){
....
for(int k = 0; k < array[array.length - 1]; k++){
do something with i,j, ... , k
}
}
}
So if I don't know the length of array first, so I can't write the certain layers for the loop, I don't know how to do it.
Thanks in advance.
Use recursion:
arr = [a, b, c, ... n]
function iterate_one_level(arr, indices) {
if (arr == []) {
do_something_with_indices(indices)
return;
}
for (let i=0; i<arr.length; i++) {
iterate_one_level(arr[1:], indices + [i])
}
}
Alternatively, your language may have something similar to itertools.product
The canonical way to do this is with recursion:
deep_loop(array[], index[]) {
if array.length == 0 // Finally reached the innermost loop
do something with index[:]
else // Go down one loop level
// loop on the first array element
for n in range 0:array[0] {
// recur on the rest of the array
// append this index to the sequence
deep_loop( array[1:], index[:] + [n] )
Related
This is the recursive function
def integerPartition(m, n):
if(n==0):
return 0
if(m ==0):
return 1
if(m<0):
return 0
return integerPartition(m,n-1) + integerPartition(m-n,n)
and this is what i have done in c++
// n -> no. of persons
// m -> amount of money to be distributed
// dp table of order (n+1)*(m+1)
long long int dp[n+1][m+1] ;
//initializing values to 0
for(i = 0; i<=n ; i++)
for(j = 0; j<= m ; j++)
dp[i][j] = 0;
Print(n,m,dp);
cout << "\n";
//Case 1 - if there is no persons i.e n = 0 answer will be 0
//Case 2 - if there is no money i.e. m = 0 there is only 1 way answer will be 1
for ( i = 1; i<= n ; i++ )
dp[i][0] = 1;
dp[i][i] = 1;
Print(n,m,dp);
for ( i = 1; i<= n ; i++){
for ( j = 1; j<= m ; j++){
dp[i][j] = dp[i][j-1] ;
if(i>=j){
dp[i][j] += dp[i-j][j];
}
// else if(i==j){
// dp[i][j] += 1;
// }
}
}
but the answers i am getting are not matching with the recursive one i don't understand what am i missing if anyone can please help me to correct i will be thankful since i have just started with dynamic programming i really am not able to figure it out
Some issues:
You seem to use non-local variables for your for loops. This is bad practice and can lead to errors that are difficult to debug. Instead
do for (int i = 1; ...etc.
dp[i][i] = 1; is not part of the for loop. You would have detected this if you would have defined i only as a variable local to the for loop.
It is good practice to always use braces for the body of a for loop (also if, else, ...etc), even if you would only have one
statement in the body.
dp[i][i] = 1; is also a bad assignment: it just is not true that integerPartition(i, i) always returns 1. It happens to be true
for small values of i, but not when i is greater than 3. For instance, integerPartition(4, 4) should return 5.
Just remove this line.
In the final nested for loop you are mixing up the row/column in your dp array. Note that you had reserved the first dimension for n and the second dimension for m, so opposite to the parameter order.
That is fine, but you do not stick to that decision in this for loop. Instead of dp[i][j-1] you should have written dp[i-1][j], and instead of dp[i-j][j] you should have
written dp[i][j-i]. And so the if condition should be adapted accordingly.
There is no return statement in your version, but maybe you just forgot to include it in the question. It should be
return dp[n][m];
Here is the corrected code:
long long int dp[n+1][m+1];
for(int i = 0; i <=n; i++) {
for(int j = 0; j <= m; j++) {
dp[i][j] = 0;
}
}
for (int i = 1; i <= n; i++) {
dp[i][0] = 1;
}
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m ; j++) {
dp[i][j] = dp[i-1][j];
if (j >= i) {
dp[i][j] += dp[i][j-i];
}
}
}
return dp[n][m];
Not sure that this technically is DP, but if your goal is to get the benefits of DP, memorization might be a better approach.
The idea is made up of 2 parts:
At the start of each call to integerPartition, look up in a table (your dp will do nicely) to see if that computation has already been done, and if it has, just return the value stored in the table.
Just before any point where integerPartition is to return a value, store it in the table.
Note that this means you don't need to try to "pivot" the original code -- it proceeds as it did originally, so you are almost guaranteed to get the same results, but without as much unnecessary re-computation (at the code of extra storage).
so, basis of your code comment,
I am going to assume you only want 1 when n > 0 and m = 0 according to your recursive code, but in dp code, you interchanged them, that is i go to upto n, and j go upto m
so updating your code, try to find the mistake
// n -> no. of persons
// m -> amount of money to be distributed
// dp table of order (n+1)*(m+1)
long long int dp[n+1][m+1] ;
//initializing values to 0
for(i = 0; i<=n ; i++)
for(j = 0; j<= m ; j++)
dp[i][j] = 0;
Print(n,m,dp);
cout << "\n";
//Case 1 - if there is no persons i.e n = 0 answer will be 0
//Case 2 - if there is no money i.e. m = 0 there is only 1 way answer will be 1
for ( i = 1; i<= n; i++){
dp[i][0] = 0;
}
for(int j = 1; j <= m; j++){
dp[0][j] = 1;
}
Print(n,m,dp);
for ( i = 1; i<= n ; i++){
for ( j = 1; j<= m ; j++){
dp[i][j] = dp[i][j-1] ;
if(i>=j){
dp[i][j] += dp[i-j][j];
}
// else if(i==j){
// dp[i][j] += 1;
// }
}
}
For instance for N highest numbers, lets say N = 3
I have a and want to get b
a = np.array([12.3,15.4,1,13.3,16.5])
b = ([15.4,13.3,16.5])
Thanks in advance.
well, my take on this:
Make a copy of the original array;
Sort the copied array to find the n highest numbers;
Go through the original array and after comparing its numbers to n highest numbers from the previous step move needed ones in a resulting array.
var a = [12.3,15.4,1,13.3,16.5], n = 3, x = 0, c =[]; // c - the resulting array
var b = a.slice(); // copy the original array to sort it
for(var i = 1; i < b.length; i++) { // insertion sorting of the copy
var temp = b[i];
for(var j = i - 1; j >= 0 && temp > b[j]; j--) b[j + 1] = b[j];
b[j + 1] = temp;
}
for(var i = 0; i < a.length; i++) { // creating the resulting array
for(var j = 0; j < n; j++) {
if(a[i] === b[j]) {
c[x] = a[i]; x++; // or just c.push(a[i]);
}
}
}
console.log(c);
The example is written in Javascript and is somewhat straightforward, but, in fact, it is quite language agnostic and does the job.
Selection Sort:
I have created a selection sorting algorithm but someone said to me its not right selection sort.
If its not right so what type of sorting is it? and how it is different then selection sorting.
Code:
void selection_Sort(int arr[] , int size){
int temp , length = size;
for(int i = 0; i < size ; i++){
for(int j = i + 1; j < size ; j++){
if(arr[i] > arr[j]){
temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
}
}
please tell me how can i improve it?
To transform this code into selection sort, you have to find index of minimal element in the inner cycle, and exchange element at this index with i-th element after inner cycle finishes.
So overall number of swaps does not exceed N (while your current code could produce about N^2/2 swaps)
You have implemented Bubble sort.
The selection sort means you should find the lowest(or bigest) element in inner cycle and then switch it with element to the left/right which is at the edge of selecting (like in the picture).
There are three similar sorting alghoritms - select sort, insert sort and bubble sort you can watch how they behave here : http://i.imgur.com/fq0A8hx.gif
You have to implement a minimum element after outer for loop.
Here is the code:
def selectionSort(arr):
for i in range(len(arr)):
# Find the minimum element in remaining
# unsorted array
min_idx = i
for j in range(i+1, len(arr)):
if arr[min_idx] > arr[j]:
min_idx = j
# Swap the found minimum element with
# the first element
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
arr = [7,4,5,9,8,2,1]
print(selectionSort(arr))
How Selection sort works?
Starting from the first element, we search the smallest element in the array, and replace it with the element in the first position.
We then move on to the second position, and look for smallest element present in the subarray, starting from index 1, till the last index.
We replace the element at the second position in the original array, or we can say at the first position in the subarray, with the second smallest element.
4.This is repeated, until the array is completely sorted.
Selection Sort in Javascript
Comparing each with the rest and swapping with the smallest from the rest
Try this code here: https://repl.it/#VinitKhandelwal/selection-sort-javascript
function selectionSort(arr){
let min;
let i;
let j;
let temp;
console.log("Input Array");
console.log(arr);
for (i = 0; i < arr.length-1; i++) {
min = i;
for (j = i+1; j < arr.length; j++) {
console.log(arr[i], arr[j]);
if (arr[j] < arr[min]) {
console.log(arr[j]);
min = j;
}
}
if (min !== i) {
temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
console.log(arr);
}
}
console.log("Sorted using Selection Sort");
return arr
}
console.log(selectionSort([5,7,6,9,8,2,1,4,3]));
// console.log(selectionSort([1,2,3,4,5,6,7,8,9])); // uncomment to try best case, i.e. sorted
var Selectionsort = function (A) {
for (var i = 0; i < A.length; i++) {
var imin = i;
for (var j = i + 1; j <= A.length; j++) {
if (A[j] < A[imin])
imin = j;
}
var tmp = A[i];
A[i] = A[imin];
A[imin] = tmp;
}
return A;
};
var A = [10, 20, 30, 40, 50, 60, 70, 80];
var Aftersorted = Selectionsort(A);
console.log(Aftersorted);
You can improve it this way:
void selectionSort(double array[], int size) {
int min;
double temp;
for (int step = 0; step < size-1; step++) {
min = step;
for (int i = step+1; i < size; i++) {
if (array [i] < array[min]) {
min = i;
}
}
temp = array[step];
array [step] = array[min];
array [min] = temp;
}
Selection Sort in C
Selection sort is basically selecting the very first element of your unsorted sub-array as a minimum and comparing it with the other elements of your sub-array to find your original minimum. Then, replacing that minimum element with the first element of your sub-array. That's all!
Here goes my code...
#include <stdio.h>
void selectionSort(int n){
int arr[n],i,j,minIndex;
printf("\nInsert %d elements:\n",n);
for(i=0;i<n;i++){
scanf("%d",&arr[i]);
}
printf("Insert complete.\n\n");
printf("Your array looks like:\n");
for(i=0;i<n;i++){
printf("%d ",arr[i]);
}
//Selection Sort Algorithm
for(i=0;i<n-1;i++){
minIndex = i;
for(j=i+1;j<n;j++){
if(arr[j] < arr[minIndex]){
minIndex = j;
}
}
//Swapping elements
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
printf("\n\nAfter sorting your array looks like:\n");
for(i=0;i<n;i++){
printf("%d ",arr[i]);
}
}
int main(){
int n;
printf("Enter number of array elements: ");
scanf("%d",&n);
selectionSort(n);
return 0;
}
Result: -
From LeetCode
Given a string S and a string T, count the number of distinct
subsequences of T in S.
A subsequence of a string is a new string which is formed from the
original string by deleting some (can be none) of the characters
without disturbing the relative positions of the remaining characters.
(ie, "ACE" is a subsequence of "ABCDE" while "AEC" is not).
Here is an example: S = "rabbbit", T = "rabbit"
Return 3.
I see a very good DP solution, however, I have hard time to understand it, anybody can explain how this dp works?
int numDistinct(string S, string T) {
vector<int> f(T.size()+1);
//set the last size to 1.
f[T.size()]=1;
for(int i=S.size()-1; i>=0; --i){
for(int j=0; j<T.size(); ++j){
f[j]+=(S[i]==T[j])*f[j+1];
printf("%d\t", f[j] );
}
cout<<"\n";
}
return f[0];
}
First, try to solve the problem yourself to come up with a naive implementation:
Let's say that S.length = m and T.length = n. Let's write S{i} for the substring of S starting at i. For example, if S = "abcde", S{0} = "abcde", S{4} = "e", and S{5} = "". We use a similar definition for T.
Let N[i][j] be the distinct subsequences for S{i} and T{j}. We are interested in N[0][0] (because those are both full strings).
There are two easy cases: N[i][n] for any i and N[m][j] for j<n. How many subsequences are there for "" in some string S? Exactly 1. How many for some T in ""? Only 0.
Now, given some arbitrary i and j, we need to find a recursive formula. There are two cases.
If S[i] != T[j], we know that N[i][j] = N[i+1][j] (I hope you can verify this for yourself, I aim to explain the cryptic algorithm above in detail, not this naive version).
If S[i] = T[j], we have a choice. We can either 'match' these characters and go on with the next characters of both S and T, or we can ignore the match (as in the case that S[i] != T[j]). Since we have both choices, we need to add the counts there: N[i][j] = N[i+1][j] + N[i+1][j+1].
In order to find N[0][0] using dynamic programming, we need to fill the N table. We first need to set the boundary of the table:
N[m][j] = 0, for 0 <= j < n
N[i][n] = 1, for 0 <= i <= m
Because of the dependencies in the recursive relation, we can fill the rest of the table looping i backwards and j forwards:
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (S[i] == T[j]) {
N[i][j] = N[i+1][j] + N[i+1][j+1];
} else {
N[i][j] = N[i+1][j];
}
}
}
We can now use the most important trick of the algorithm: we can use a 1-dimensional array f, with the invariant in the outer loop: f = N[i+1]; This is possible because of the way the table is filled. If we apply this to my algorithm, this gives:
f[j] = 0, for 0 <= j < n
f[n] = 1
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (S[i] == T[j]) {
f[j] = f[j] + f[j+1];
} else {
f[j] = f[j];
}
}
}
We're almost at the algorithm you gave. First of all, we don't need to initialize f[j] = 0. Second, we don't need assignments of the type f[j] = f[j].
Since this is C++ code, we can rewrite the snippet
if (S[i] == T[j]) {
f[j] += f[j+1];
}
to
f[j] += (S[i] == T[j]) * f[j+1];
and that's all. This yields the algorithm:
f[n] = 1
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
f[j] += (S[i] == T[j]) * f[j+1];
}
}
I think the answer is wonderful, but something may be not correct.
I think we should iterate backwards over i and j. Then we change to array N to array f, we looping j forwards for not overlapping the result last got.
for (int i = m-1; i >= 0; i--) {
for (int j = 0; j < n; j++) {
if (S[i] == T[j]) {
N[i][j] = N[i+1][j] + N[i+1][j+1];
} else {
N[i][j] = N[i+1][j];
}
}
}
I have this problem , where given an array of positive numbers i have to find the maximum sum of elements such that no two adjacent elements are picked. The maximum has to be less than a certain given K. I tried thinking on the lines of the similar problem without the k , but i have failed so far.I have the following dp-ish soln for the latter problem
int sum1,sum2 = 0;
int sum = sum1 = a[0];
for(int i=1; i<n; i++)
{
sum = max(sum2 + a[i], sum1);
sum2 = sum1;
sum1 = sum;
}
Could someone give me tips on how to proceed with my present problem??
The best I can think of off the top of my head is an O(n*K) dp:
int sums[n][K+1] = {{0}};
int i, j;
for(j = a[0]; j <= K; ++j) {
sums[0][j] = a[0];
}
if (a[1] > a[0]) {
for(j = a[0]; j < a[1]; ++j) {
sums[1][j] = a[0];
}
for(j = a[1]; j <= K; ++j) {
sums[1][j] = a[1];
}
} else {
for(j = a[1]; j < a[0]; ++j) {
sums[1][j] = a[1];
}
for(j = a[0]; j <= K; ++j) {
sums[1][j] = a[0];
}
}
for(i = 2; i < n; ++i) {
for(j = 0; j <= K && j < a[i]; ++j) {
sums[i][j] = max(sums[i-1][j],sums[i-2][j]);
}
for(j = a[i]; j <= K; ++j) {
sums[i][j] = max(sums[i-1][j],a[i] + sums[i-2][j-a[i]]);
}
}
sums[i][j] contains the maximal sum of non-adjacent elements of a[0..i] not exceeding j. The solution is then sums[n-1][K] at the end.
Make a copy (A2) of the original array (A1).
Find largest value in array (A2).
Extract all values before the it's preceeding neighbour and the values after it's next neighbour into a new array (A3).
Find largest value in the new array (A3).
Check if sum is larger that k. If sum passes the check you are done.
If not you will need to go back to the copied array (A2), remove the second larges value (found in step 3) and start over with step 3.
Once there are no combinations of numbers that can be used with the largest number (i.e. number found in step 1 + any other number in array is larger than k) you remove it from the original array (A1) and start over with step 0.
If for some reason there are no valid combinations (e.g. array is only three numbers or no combination of numbers are lower than k) then throw an exception or you return null if that seems more appropriate.
First idea: Brute force
Iterate all legal combination of indexes and build the sum on the fly.
Stop with one sequence when you get over K.
keep the sequence until you find a larger one, that is still smaller then K
Second idea: maybe one can force this into a divide and conquer thing ...
Here is a solution to the problem without the "k" constraint which you set out to do as the first step: https://stackoverflow.com/a/13022021/1110808
The above solution can in my view be easily extended to have the k constraint by simply amending the if condition in the following for loop to include the constraint: possibleMax < k
// Subproblem solutions, DP
for (int i = start; i <= end; i++) {
int possibleMaxSub1 = maxSum(a, i + 2, end);
int possibleMaxSub2 = maxSum(a, start, i - 2);
int possibleMax = possibleMaxSub1 + possibleMaxSub2 + a[i];
/*
if (possibleMax > maxSum) {
maxSum = possibleMax;
}
*/
if (possibleMax > maxSum && possibleMax < k) {
maxSum = possibleMax;
}
}
As posted in the original link, this approach can be improved by adding memorization so that solutions to repeating sub problems are not recomputed. Or can be improved by using a bottom up dynamic programming approach (current approach is a recursive top down approach)
You can refer to a bottom up approach here: https://stackoverflow.com/a/4487594/1110808