this is a paragraph from data structure book, by Narasimha Karumanchi (disjoint set ADT)
fast find implementation(quick find)
this method uses an array, where the array contains the set name for each element.
In this representation to perform union(a,b)[assuming that a, is in set i and b is in set j] we need to scan the complete array and change all i to j. this take O(n).
my question 1
if find operation takes O(1) then why scan complete array and change all i to j ,only two of them need to change , so how it is O(n)
============
(book 8.8 section)
using an array which stores the parent of each element instead of using root as its set name, solve union O(n)
my 2. question
how does it solve issue using parent?
And how both root and parent approaches gives us skew tree?
Consider that you have 8 elements in 2 sets, where the set identifiers are 1 and 2 (so i = 1 and j = 2 in your description).
Assume that 4 elements are in set 1 (elements 0, 1, 3, 7) and 4 elements are in set 2 (elements 2, 4, 5, 6).
Quick find implementation would represent this array as:
[ 1, 1, 2, 1, 2, 2, 2, 1 ]
And as the following representation (both elements 1 and 2 have self-loops):
1 2
/ | \ / | \
0 3 7 4 5 6
If you perform union(1, 2) and only update the set identifier (let’s assume that we are updating the elements in set 2 to point to set 1), then you would have an array such as:
[ 1, 1, 1, 1, 2, 2, 2, 1 ]
If you perform find(2) you get as a result the identifier 1, which is correct.
But if you perform find(4) you get as a result the identifier 2, which is incorrect because element 4 now belongs to set 1.
So you have to scan the complete array (and therefore the operation has time complexity O(n)) to update the identifiers, to have the following array as a result of the union operation:
[ 1, 1, 1, 1, 1, 1, 1, 1 ]
And the following representation (with 1 having a self-loop)
1
/ / | | \ \ \
0 2 3 4 5 6 7
As I'm sure you will see later in the book, there are more efficient implementations of the union-find data structure, which are based on union by rank and path compression.
Related
I encountered a problem of counting minimum moves to set all elements in array to 0. An array consist of integer values from 0 to 6 (including 6) and the conditions are:
It is possible to change one or more subsequent values in one step (move) by the same value e.g. change values from index 5 to 8 (so indexes 5, 6, 7, 8) by adding 2 but it is forbidden to change indexes 5, 6, 8 (without 7, so they are not subsequent) by adding 2 in one step (I would have to change 5, 6 firstly and then in next step 8 to do it correctly).
Array consist of values from 0 to 6 e.g. when value is 5 and you add 3, it will be set on 1 because 6 is maximum and with value higher than 6 it ,,goes from start (0)" or if value is 1 and you substract 2, finally it will be set on 6 because 0 is minimum and with value lower than 0 it ,,goes from end (6)". In other words -1 will be equal to 6, -2 equal to 5, 8 equal to 1.
I have to write algorithm, which solves described problem and have no idea how should I start.
I tried to count occurrences of every number and then in first step set values to 0 in array from first occurrence to last but using this approach in some cases answer is wrong. For example array with values {1,3,2,2,2}. Step 1 - set 2 to 0 {1,3,0,0,0} and then in two separated moves set 1 and 3 to 0 what finally gives 3 moves. Valid answer is 2 moves because in first step values from 3 to last 2 should be decreased by 2 - {1,1,0,0,0} and then in next move decrease first two values by 1 - so 2 moves.
I have a spreadsheet I'm creating and I have an ARRAYFORMULA for incrementing the number of a field based on another field. My formula looks like this (NOTE: my rows start on row 4 that is why there is a ROW(A4:A)-3):
=ARRAYFORMULA(IF(ROW(A4:A) = 4, 1, IF(B4:B = 1, ROW(A4:A)-3, (ROW(A4:A)-3)-(B4:B - 1))))
What I'm doing is creating groups (A) and then have a sequence counter (B) which is the number of rows within the group. I want the result to look like this where the A just picks up from where it left off (Note: B is manually entered):
A
B
1
1
2
1
3
1
3
2
3
3
4
1
5
1
However, my result is looking this this:
A
B
1
1
2
1
3
1
3
2
3
3
6
1
7
1
I know ROW gets me the row number but when I try and use INDEX formula:
=ARRAYFORMULA(IF(ROW(G4:G) = 4, 1, IF(H4:H = 1, INDEX(G4:G, ROW(G4:G)-1, 1) + 1, INDEX(G4:G, ROW(G4:G)-1, 1)))
to get the actual value of the prior cell I get a constant flashing like it's stuck in an infinite loop of some sort. I know I can probably just accomplish this without ARRAYFORMULA however, this spreadsheet will be shared and contains many other formulas that I just don't want people to have to cut and copy from the row above and get formulas all messed up. I'm dealing with non-technical people that need something to just work very simple.
Sample:
https://docs.google.com/spreadsheets/d/1FqndR4oTm_uaO7aUxYSgb3p0bZ6yBz-KnjUAD8kctd4/edit?usp=drivesdk
use:
=ARRAYFORMULA(COUNTIFS(A4:A, A4:A, ROW(A4:A), "<="&ROW(A4:A)))
reverse:
=ARRAYFORMULA(MMULT(TRANSPOSE((SEQUENCE(COUNTA(B4:B))<=
SEQUENCE(1, COUNTA(B4:B)))*IF(INDIRECT("B4:B"&COUNTA(B4:B)+ROW(B4)-1)=1, 1)),
SEQUENCE(COUNTA(B4:B))^0))
I am trying to create a simple Algorithm in Dart but I think the programming language doesn't matter it is more about the Algorithm:
I am trying to make 2 lists of pairs of numbers depending on "row" and "column" for example:
col_1
col_2
1
2
3
4
5
6
7
8
9
10
=> I need a Algorithm that makes me 2 lists of numbers:
first list: 2,3,6,7,10...
second list: 4,5,8,9...
But this must also work when the "columns" change like that:
col_1
col_2
col_3
1
2
3
4
5
6
7
8
9
this time the first list must be:
3,4,9...
the second list:
6,7 ...
anyone has an Idea on how I could achieve this with a simple calculation? or algorithm depending on the "Maximum" amount of numbers?
You're probably looking for the modulo operator %
Directly, it can create a repeating series based upon the remainder of dividing by the value
For example, you could place your values into the Nth list in a list of lists (whew)
>>> cols = [[],[],[]]
>>> for x in range(12):
... cols[x % 3].append(x)
...
>>> cols
[[0, 3, 6, 9], [1, 4, 7, 10], [2, 5, 8, 11]]
0%5 --> 0
1%5 --> 1
...
11%5 --> 1
To massage values when you have (for example) some increment of 1, you can do a little math
>>> for x in range(12):
... print("x={} is in column {}".format(x + 1, (x % 3) + 1 ))
...
x=1 is in column 1
x=2 is in column 2
x=3 is in column 3
x=4 is in column 1
x=5 is in column 2
x=6 is in column 3
x=7 is in column 1
x=8 is in column 2
x=9 is in column 3
x=10 is in column 1
x=11 is in column 2
x=12 is in column 3
Note you may need to do some extra work to either
know how many values you need to fill all the columns
count and stop when you have enough rows
Examples are in Python because I'm most familiar with it
Note that work like [[],[],[]] should largely be avoided if a better collection is available (perhaps a dict of lists with column-name keys or Pandas DataFrame), but it makes for a good illustration
With a little discussion, https://oeis.org/A042964 seems like the solution, which suggests the following for testing entries for set membership
binomial(m+2, m) mod 2 = 0
in Python, this could be
>>> from scipy.special import binom # 3rd party math library
>>> for m in range(1, 15):
... print("{} belongs in list {}".format(m, 1 if binom(m+2, m) % 2 == 0 else 2))
...
1 belongs in list 2
2 belongs in list 1
3 belongs in list 1
4 belongs in list 2
5 belongs in list 2
6 belongs in list 1
7 belongs in list 1
8 belongs in list 2
9 belongs in list 2
10 belongs in list 1
11 belongs in list 1
12 belongs in list 2
13 belongs in list 2
14 belongs in list 1
If only the first list is desired, entries can be directly generated by the formula a(n)=2*n+2-n%2 (refer to PROG on OEIS page), rather than testing values for membership
>>> a = lambda n: 2*n+2-n%2
>>> [a(n) for n in range(10)]
[2, 3, 6, 7, 10, 11, 14, 15, 18, 19]
The question is:
Given an unsorted array, sort it in such a way that the first element is the largest, the second element is the smallest, the third element is the second largest, etc.
Follow up: Can you do it without using extra space?
Example:
[2, 4, 3, 5, 1] -> [5, 1, 4, 2, 3]
I want to be able to sort the array without using extra space. What is the most efficient solution? I can only think of an O(n2) solution that loops through the array to find the next largest and next smallest elements. Is there a more efficient solution?
I've looked at the related questions Sorting an array with alternate smallest and largest values and Sorting an array with alternate smallest-largest values but the answers didn't help with my question.
precondition : using deque.
1.sorting the array.
loop)
2.pop_back(array) -> insert that element in i*2 position.
example) 1, 2, 3, 4, 5, 6, 7
a) 7 (insert to 0) -> 1 2 3 4 5 6 => 7 1 2 3 4 5 6
b) 6 (insert to 2) -> 7 1 2 3 4 5 => 7 1 6 2 3 4 5
c) 5 (insert to 4) -> 7 1 6 2 3 4 => 7 1 6 2 5 3 4 (finished)
Its complexity maybe O(nlog(n)) + O(n/2)
I have two columns with an int inside for each field like that:
1 2
2 3
4 1
5 6
And I also have a larger grid, like that:
1 1 1 1 2 2 1
1 2 3 4 2 1 1
1 3 2 3 1 3 2
1 3 6 5 6 1 3
The two columns let me know that I have to replace every 2 with 1, every 3 with 2 and every 1 with 4 in the larger grid, so the result can be
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 1 1 1 1 1
1 1 5 5 5 1 1
If I proceed directly replacing in the second table with the first entry, I won't be able to proceed with the second, since there are no more "2".
How can I solve that?
If the problem is not that clear, I give you this article that explains the problem, without showing any concrete solution.
http://www.labbookpages.co.uk/software/imgProc/blobDetection.html#table
EDIT: I have an input like that:
Table of exchanges
3 2
4 1
Table to correct
1111111111111111111111111111
1122111111111111111111113311
1122211111111111111111133311
1112221111111111111111333111
1111222111111111111113331111
1111122211111111111133311111
1111112221111111111333111111
1111111222111111113331111111
1111111122211111133311111111
1111111111222113331111111111
1111111111122222211111111111
1111111111112222111111111111
1111111111112222111111111111
1111111111122222211111111111
1111111111222442221111111111
1111111112224444222111111111
1111111122244444422211111111
1111111222444444442221111111
1111112224444444444222111111
1111122244444444444422211111
1111222444444444444442221111
1112224444444444444444222111
1122244444444444444444422211
1122444444444444444444442211
1111111111111111111111111111
(this is an X)
In this case was pretty easy to make the replacement, since I don't have another reference to 2 except than 3 and 1 for 4, but most of cases do.
What I did was to directly go and replace the 3's with 2 and the 1's with 4.
As you have found out, you can't apply the transformations one after another to your whole grid. Instead, you should find the correct transformation for each grid cell.
A rule that assigns a unique value based on the input is called a map. The identity map just maps each value to itself; these are the elements you don't change. Start with an identity map and then adjust it according to your replacement pairs.
Here's a simple program based on your first example. Make sure that each input value is a valid index in the map array.
#include <stdlib.h>
#include <stdio.h>
int main()
{
int grid[4][7] = {
{1, 1, 1, 1, 2, 2, 1},
{1, 2, 3, 4, 2, 1, 1},
{1, 3, 2, 3, 1, 3, 2},
{1, 3, 6, 5, 6, 1, 3},
};
int map[10] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9 // identity
};
int i, j;
map[2] = 1; // adjust map to
map[3] = 2; // replacement pairs
map[1] = 4;
map[6] = 5;
// apply mapping rule
for (j = 0; j < 4; j++) {
for (i = 0; i < 7; i++) {
grid[j][i] = map[grid[j][i]];
}
}
// print grid
for (j = 0; j < 4; j++) {
for (i = 0; i < 7; i++) {
printf("%d ", grid[j][i]);
}
puts("");
}
return 0;
}
Check for Dependencies, In changer column values <2 3 1 6>. <1 6> can easily change and not depends. Afterward you need to save the states for every Integer.
Take array for store index position, i.e. if(grid==1) then one[]=grid.value; if(grid==2) then two[]=grid,value; respectively.
Now, change grid[one[]]=2; and grid[two[]]=1; Simply.
1- Duplicate the matrix (d). This will not be modified, just an aux.
2- For each cell in (d), compare (d)[cell] with every cell in 2nd row of your 2 columns.
2.1- On match, set in your result matrix (wich has been duplicated before), the value of the cell in the first column at the same (d) position.
3- Return the matrix modified.