Question: How to remove duplicates in an array of N with N integers,
The time complexity is O (n) and the space complexity is O (1 ).
// There is no problem with the following ideas, but there is a problem with the algorithm. For the corrected algorithm, see the following.
/// <Summary>
/// Array of repeated Integers to be removed. Note that I have not processed negative numbers here,
/// In fact, in the case of negative numbers, you only need to separate the groups with 0 and then use the following algorithms to process them respectively.
/// In addition, because it is an integer, 32-bit symbols are not considered here, but 31 digits are considered.
/// Question analysis: from the requirement, if an array is sorted, it is very easy to remove duplicates, so it is converted
/// Search for sorting algorithms. This algorithm must meet the following requirements: linear time, constant memory, and in-situ replacement. However, such algorithms cannot be sorted by comparison,
/// Only the base sorting, bucket sorting, and count sorting are supported. However, the base sorting depends on the bit sorting, and the bit sorting is required to be stable,
/// The auxiliary space cannot be used too much and the counting sorting is excluded. Because the counting sorting cannot be replaced in situ, the bucket sorting also requires the auxiliary space.
/// Base sorting. However, the question is how to select the bit sorting. Because the bit is only 0 and 1, it has its own particularity. Using the fast sorting grouping can achieve linearity,
/// But the problem is that this algorithm is linear, in-situ replacement, but unstable. Therefore, a mechanism should be used to ensure the stability of fast sorting. After a while,
/// It is found that, if the sorting starts from the high position, assuming that the first K bits are sorted, only the same K bits are sorted, the first K digits are not the same and cannot be
/// Equal, the K + 1 position does not affect the result, and the same sorting of the first K bits does not affect the instability of the fast sorting, this instability will not affect the final result.
/// The following is the algorithm:
/// </Summary>
/// <Param name = "A"> </param>
Private void bitsortanddelrepeatorsa (INT [])
{
// Obtain the array Length
Int then = A. length;
// The sorting starts from the high position to the low position. Here, the sorting starts from 31 bits, and 32 bits are not considered as symbols, or they are considered separately.
For (INT I = 31; I> = 1; I --)
{
// The value before the current sorting. You can group the values only when the values are the same. If the values are different, start another sorting.
// This is critical. Otherwise, the final result will be affected due to the instability of the fast sorting.
Int theprvcb = A [0]> (I );
// The start position of the quick sort, which will change
Int thes = 0;
// Insert point
Int thei = thes;
// Integer primitive, select the number of the start position of the quick rank.
Int theaxnum = A [thei];
// Binary base, used to test whether a digit is 0
Int thebase = 1 <(I-1 );
// Bitwise primitive,
Int theaxbit = (theaxnum> (I-1) & 1; // (A [thei] & (thebase)> 0? 1: 0;
// Segment fast sorting, but the overall time complexity is the same as that of fast grouping.
For (Int J = 1; j <then; j ++)
{
// Obtain the bitwise value that has been sorted before the current array value.
Int thetmpprvcb = A [J]> (I );
// If the positions already exceeded are not the same, start the fast sorting again.
If (thetmpprvcb! = Theprvcb)
{
A [thes] = A [thei];
A [thei] = theaxnum;
Thes = J;
TheI = thes;
Theaxnum = A [thei];
Theaxbit = A [thei] & thebase;
Theprvcb = thetmpprvcb;
Continue;
}
// If the values are the same, sort them in the quick order.
Int theaj = (a [J]> (I-1) & 1; // (A [J] & (thebase)> 0? 1: 0;
If (theaj <= theaxbit)
{
TheI ++;
Int thetmp = A [J];
A [J] = A [thei];
A [thei] = thetmp;
}
}
// Note the last exchange.
A [thes] = A [thei];
A [thei] = theaxnum;
}
}
Remove duplicates: you only need to traverse the preceding sorting results.
Private int [] deleterepeatedint (INT [])
{
Int n = A. length;
// Sort the count from the low position to the high position. Because it is an integer, it is assumed that it is a positive number.
For (INT I = 1; I <= 32; I ++)
{
Countsort2 (A, I );
}
// Remove the number of duplicates
Int theprenum = int. minvalue;
List <int> theret = new list <int> ();
For (INT I = 0; I <n; I ++)
{
If (A [I]! = Theprenum)
{
Theret. Add (A [I]);
Theprenum = A [I];
}
}
Return theret. toarray ();
}
========================================================== ==============
Sorting Algorithm correction
/// <Summary>
/// Array of repeated Integers to be removed. Note that I have not processed negative numbers here,
/// In fact, in the case of negative numbers, you only need to separate the groups with 0 and then use the following algorithms to process them respectively.
/// In addition, because it is an integer, 32-bit symbols are not considered here, but 31 digits are considered.
/// Question analysis: from the requirement, if an array is sorted, it is very easy to remove duplicates, so it is converted
/// Search for sorting algorithms. This algorithm must meet the following requirements: linear time, constant memory, and in-situ replacement. However, such algorithms cannot be sorted by comparison,
/// Only the base sorting, bucket sorting, and count sorting are supported. However, the base sorting depends on the bit sorting, and the bit sorting is required to be stable,
/// The auxiliary space cannot be used too much and the counting sorting is excluded. Because the counting sorting cannot be replaced in situ, the bucket sorting also requires the auxiliary space.
/// Base sorting. However, the question is how to select the bit sorting. Because the bit is only 0 and 1, it has its own particularity. Using the fast sorting grouping can achieve linearity,
/// But the problem is that this algorithm is linear, in-situ replacement, but unstable. Therefore, a mechanism should be used to ensure the stability of fast sorting. After a while,
/// It is found that, if the sorting starts from the high position, assuming that the first K bits are sorted, only the same K bits are sorted, the first K digits are not the same and cannot be
/// Equal, the K + 1 position does not affect the result, and the same sorting of the first K bits does not affect the instability of the fast sorting, this instability will not affect the final result.
/// The following is the algorithm:
/// </Summary>
/// <Param name = "A"> </param>
Private void bitsortanddelrepeatorsa (INT [])
{
// Obtain the array Length
Int then = A. length;
// The sorting starts from the high position to the low position. Here, the sorting starts from 31 bits, and 32 bits are not considered as symbols, or they are considered separately.
For (INT I = 31; I> = 1; I --)
{
// The value before the current sorting. You can group the values only when the values are the same. If the values are different, start another sorting.
// This is critical. Otherwise, the final result will be affected due to the instability of the fast sorting.
Int theprvcb = A [0]> (I );
// The start position of the quick sort, which will change
Int thes = 0;
// Insert point
Int thei = theS-1;
// Binary base, used to test whether a digit is 0
Int thebase = 1 <(I-1 );
// The bitwise primitive is always 0,
Int theaxbit = 0;
// Segment fast sorting, but the overall time complexity is the same as that of fast grouping.
For (Int J = 0; j <then; j ++)
{
// Obtain the bitwise value that has been sorted before the current array value.
Int thetmpprvcb = A [J]> (I );
// If the positions already exceeded are not the same, start the fast sorting again.
If (thetmpprvcb! = Theprvcb)
{
Thes = J;
TheI = thes-1;
Theaxbit = 0;
Theprvcb = thetmpprvcb;
J --; // start the row again and return to the first position.
Continue;
}
// If the previous number is the same, search for the first 1st 1, and Thi points to it
// If the values are the same, sort them in the quick order.
Int theaj = (a [J] & (thebase)> 0? 1: 0; // (A [J] & (thebase)> 0? 1: 0; (a [J]> (I-1) & 1
// If you start the row again, search for the first 1 and point thei to it. This can reduce the switching speed and speed up.
If (thei <thes)
{
If (theaj = 0)
{
Continue;
}
TheI = J; // continue ensures that J starts from thei + 1.
Continue;
}
// Switch.
If (theaj <= theaxbit)
{
Int thetmp = A [J];
A [J] = A [thei];
A [thei] = thetmp;
TheI ++;
}
}
}
}
Tested, the algorithm complexity is less than 32 * n.
Note: in fact, the practical value of this interview question is still very large. Here it is an integer. If it is a string sort, you can use a similar algorithm, and the space requirement is relatively small.
Disclaimer: this algorithm is my original algorithm. Please indicate the source for reprinting. Thank you!
Note: This algorithm is not stable either.
In addition: Interview Questions collection, you can go to the July blog to see, will be very fruitful: http://blog.csdn.net/v_JULY_v