タイトル
大きさnの配列を指定し、要素の大部分は、その中に見つかりました。配列内の要素のほとんどは、n / 2より⌊⌋大きい要素出現数を意味します。
あなたは、配列が空であると仮定することができ、与えられた配列のほとんどの要素が常にあります。
例1
输入: [3,2,3]
输出: 3
例2
输入: [2,2,1,1,1,2,2]
输出: 2
思考
- マップを使用して、再配列を横断し、各番号が表示された回数を記録します。
- 再び横断、最初の出現数を見つけるためには、N / 2⌋要素⌊より大きい。
コードA
class Solution {
public:
int majorityElement(vector<int>& nums) {
map<int,int> m;
int half = ( nums.size() - 1 ) >> 1;
int res = 0;
for ( auto& n : nums )
++m[n];
for ( auto&n : nums ) {
if ( m[n] > half ) {
res = n;
break;
}
}
return res;
}
};
アイデア2
- N / 2⌋要素⌊より大きい。配列が注文した場合、回数は数がn / 2⌊より大きく表示されます⌋、その後、⌊N / 2⌋この要素では確かにあります。
- 数mは、mは左側のM未満の数である場合、Mより大きい数mの右側に、得られた高速行のアイデアを使用することが可能です。
- mが位置⌊N / 2に等しい場合⌋、それが返されます。
- 位置は、以下/ 2⌋、次にMの右迅速ドレインに、新たなMを見つけるN⌊m以下である場合。
- それ以外の場合は、高速にランクmは新しいメートルを見つけるために残しません。
- ここで、⌊N / 2⌋位置を見つけるために、上記のノウハウを繰り返します。
コード2
class Solution {
public:
// 不用额外空间
int majorityElement(vector<int>& nums) {
int half = nums.size() >> 1;
helper( nums, 0, nums.size() - 1, half );
return nums[half];
}
void helper( vector<int>& nums, int lo, int hi, const int& half ) {
int mid = partition( nums, lo, hi );
if ( mid == half )
return;
if ( mid > half )
helper( nums, lo, mid - 1, half );
else
helper( nums, mid + 1, hi, half );
}
int partition( vector<int>& nums, int lo, int hi ) {
int index = lo + rand() % ( hi - lo + 1 );
swap( nums[lo], nums[index] );
int pivot = nums[lo];
while ( lo < hi ) {
while ( lo < hi && pivot <= nums[hi] )
--hi;
nums[lo] = nums[hi];
while ( lo < hi && pivot >= nums[lo] )
++lo;
nums[hi] = nums[lo];
}
nums[lo] = pivot;
return lo;
}
void swap( int& a, int& b ) {
int temp = a;
a = b;
b = temp;
return;
}
};