按 1 位数对整数排序。我使用一种排序函数对向量进行排序?但为什么排序不起作用?
Sort Integers by The Number of 1 Bits . I used one sort function to sort the vector ? But why sort is not working?
按 1 的位数对整数排序
力扣: Problem Link
示例测试用例:
示例 1:
Input: arr = [0,1,2,3,4,5,6,7,8]
Output: [0,1,2,4,8,3,5,6,7]
Explantion: [0] is the only integer with 0 bits.
[1,2,4,8] all have 1 bit.
[3,5,6] have 2 bits.
[7] has 3 bits.
The sorted array by bits is [0,1,2,4,8,3,5,6,7]\
示例 2:
Input: arr = [1024,512,256,128,64,32,16,8,4,2,1]
Output: [1,2,4,8,16,32,64,128,256,512,1024]
Explantion: All integers have 1 bit in the binary representation, you should just sort them in ascending order.
我的解决方案:
class Solution {
public:
unsigned int setBit(unsigned int n){
unsigned int count = 0;
while(n){
count += n & 1;
n >>= 1;
}
return count;
}
vector<int> sortByBits(vector<int>& arr) {
map<int,vector<int>>mp;
for(auto it:arr){
mp[setBit(it)].push_back(it);
}
for(auto it:mp){
vector<int>vec;
vec=it.second;
sort(vec.begin(),vec.end()); //This Sort Function of vector is not working
}
vector<int>ans;
for(auto it:mp){
for(auto ele:it.second){
ans.push_back(ele);
}
}
return ans;
}
};
在我的代码中,为什么排序功能不起作用?
[1024,512,256,128,64,32,16,8,4,2,1]
上面的测试用例输出是[1024,512,256,128,64,32,16,8,4,2,1]
,因为排序功能不起作用。正确的输出是 [1,2,4,8,16,32,64,128,256,512,1024]
注意: 在上面的测试用例示例中,测试用例的每个元素只有一个设置位(1)
vector<int>vec
是地图中副本的副本,然后被丢弃。尝试:
for(auto& entry:mp){
vector<int>&vec=entry.second;
sort(vec.begin(),vec.end());
}
您的其他 for 循环也应使用引用以提高效率,但不会影响行为。
作为您在 //This sort function ...
中的迭代
引用 mp
作为映射内部值的副本,排序函数不会对其中的向量进行排序,而是对它的副本进行排序。这不影响原来的vector<int>
里面的mp
。因此,不会产生任何影响。您应该将地图内的矢量作为参考,如下所示:
class Solution {
public:
unsigned int setBit(unsigned int n) {
unsigned int count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return count;
}
vector<int> sortByBits(vector<int>& arr) {
map<int, vector<int>>mp;
for (auto it : arr) {
mp[setBit(it)].push_back(it);
}
for (auto& it : mp) {
sort(it.second.begin(), it.second.end()); //Now the sort function works
}
vector<int>ans;
for (auto it : mp) {
for (auto ele : it.second) {
ans.push_back(ele);
}
}
return ans;
}
};
虽然您的解决方案中存在更多设计问题,但这将是一个修改最少的解决方案。
这是内存高效且快速的解决方案。我不知道你为什么要使用地图和额外的矢量。我们可以在没有任何额外内存的情况下有效地解决这个问题。我们只需要创建一个 Comparator 函数,它将根据我们自己的要求对元素进行排序。如果您需要进一步的代码帮助(或者如果您觉得难以理解我的代码),请在评论中告诉我。我正在使用 __builtin_popcount() 函数,它将 return 设置数字中的位数。
bool sortBits(const int a, const int b){ //Comparator function to sort elements according to number of set bits
int numOfBits1 = __builtin_popcount(a);
int numOfBits2 = __builtin_popcount(b);
if(numOfBits1 == numOfBits2){ //if number of set bits are same, then sorting the elements according to magnitude of element (greater/smaller element)
return a < b;
}
return (numOfBits1 < numOfBits2); //if number of set bits are not same, then sorting the elements according to number of set bits in element
}
class Solution {
public:
vector<int> sortByBits(vector<int>& arr) {
sort(arr.begin(),arr.end(), sortBits);
return arr;
}
};
我假设 OP 只是在学习,因此摆弄各种数据结构等可以具有一定的教育价值。尽管如此,只有一条评论指出问题的开始方法是错误的,练习的重点是找到一种比较数字的自定义方法,首先按位数,然后按值。
提供 std::sort
是允许的(OP 使用它),我想整个解决方案在概念上归结为 sth likes this(但我没有用 LeetCode 验证它):
template <typename T>
struct Comp
{
std::size_t countBits(T number) const
{
size_t count;
while(number) {
count += number & 1;
number>>=1;
}
return count;
}
bool operator()(T lhs, T rhs) const
{
/*
auto lb{countBits(lhs)};
auto rb{countBits(rhs)};
return lb==rb ? lhs < rhs : lb < rb;
* The code above is the manual implementation of the line below
* that utilizes the standard library
*/
return std::tuple{countBits(lhs), lhs} < std::tuple{countBits(rhs), rhs};
}
};
class Solution {
public:
void sortByBits(vector<int>& arr) {
std::sort(begin(arr), end(arr), Comp<int>{});
}
};
可能还可以进一步改进,但我会把它作为分析的起点。
该问题已经过评估,并且已经解释了修复方法。
我想给出2个additional/alternative个解决方案。
(像我这样的老人和头发花白的人还会在《Hackers Delight》一书中找到另外 5 个最有效的解决方案)
两种变体都导致使用 std::sort
和 lambda 的单语句解决方案。
请看:
#include <algorithm>
#include <vector>
#include <iostream>
#include <bitset>
// Solution
class Solution {
public:
std::vector<int> sortByBits(std::vector<int>& arr) {
std::sort(arr.begin(), arr.end(), [](const unsigned int i1, const unsigned int i2)
{ size_t c1{ std::bitset<14>(i1).count() }, c2{ std::bitset<14>(i2).count() }; return c1 == c2 ? i1 < i2 : c1 < c2; });
//{ int c1=std::popcount(i1), c2=std::popcount(i2); return c1 == c2 ? i1 < i2 : c1 < c2; });
return arr;
}
};
// Test
int main() {
std::vector<std::vector<int>> testData{
{0,1,2,3,4,5,6,7,8},
{1024,512,256,128,64,32,16,8,4,2,1}
};
Solution s;
for (std::vector<int>& test : testData) {
for (const int i : s.sortByBits(test)) std::cout << i << ' ';
std::cout << '\n';
}
}
按 1 的位数对整数排序
力扣: Problem Link
示例测试用例:
示例 1:
Input: arr = [0,1,2,3,4,5,6,7,8]
Output: [0,1,2,4,8,3,5,6,7]
Explantion: [0] is the only integer with 0 bits.
[1,2,4,8] all have 1 bit.
[3,5,6] have 2 bits.
[7] has 3 bits.
The sorted array by bits is [0,1,2,4,8,3,5,6,7]\
示例 2:
Input: arr = [1024,512,256,128,64,32,16,8,4,2,1]
Output: [1,2,4,8,16,32,64,128,256,512,1024]
Explantion: All integers have 1 bit in the binary representation, you should just sort them in ascending order.
我的解决方案:
class Solution {
public:
unsigned int setBit(unsigned int n){
unsigned int count = 0;
while(n){
count += n & 1;
n >>= 1;
}
return count;
}
vector<int> sortByBits(vector<int>& arr) {
map<int,vector<int>>mp;
for(auto it:arr){
mp[setBit(it)].push_back(it);
}
for(auto it:mp){
vector<int>vec;
vec=it.second;
sort(vec.begin(),vec.end()); //This Sort Function of vector is not working
}
vector<int>ans;
for(auto it:mp){
for(auto ele:it.second){
ans.push_back(ele);
}
}
return ans;
}
};
在我的代码中,为什么排序功能不起作用?
[1024,512,256,128,64,32,16,8,4,2,1]
上面的测试用例输出是[1024,512,256,128,64,32,16,8,4,2,1]
,因为排序功能不起作用。正确的输出是 [1,2,4,8,16,32,64,128,256,512,1024]
注意: 在上面的测试用例示例中,测试用例的每个元素只有一个设置位(1)
vector<int>vec
是地图中副本的副本,然后被丢弃。尝试:
for(auto& entry:mp){
vector<int>&vec=entry.second;
sort(vec.begin(),vec.end());
}
您的其他 for 循环也应使用引用以提高效率,但不会影响行为。
作为您在 //This sort function ...
中的迭代
引用 mp
作为映射内部值的副本,排序函数不会对其中的向量进行排序,而是对它的副本进行排序。这不影响原来的vector<int>
里面的mp
。因此,不会产生任何影响。您应该将地图内的矢量作为参考,如下所示:
class Solution {
public:
unsigned int setBit(unsigned int n) {
unsigned int count = 0;
while (n) {
count += n & 1;
n >>= 1;
}
return count;
}
vector<int> sortByBits(vector<int>& arr) {
map<int, vector<int>>mp;
for (auto it : arr) {
mp[setBit(it)].push_back(it);
}
for (auto& it : mp) {
sort(it.second.begin(), it.second.end()); //Now the sort function works
}
vector<int>ans;
for (auto it : mp) {
for (auto ele : it.second) {
ans.push_back(ele);
}
}
return ans;
}
};
虽然您的解决方案中存在更多设计问题,但这将是一个修改最少的解决方案。
这是内存高效且快速的解决方案。我不知道你为什么要使用地图和额外的矢量。我们可以在没有任何额外内存的情况下有效地解决这个问题。我们只需要创建一个 Comparator 函数,它将根据我们自己的要求对元素进行排序。如果您需要进一步的代码帮助(或者如果您觉得难以理解我的代码),请在评论中告诉我。我正在使用 __builtin_popcount() 函数,它将 return 设置数字中的位数。
bool sortBits(const int a, const int b){ //Comparator function to sort elements according to number of set bits
int numOfBits1 = __builtin_popcount(a);
int numOfBits2 = __builtin_popcount(b);
if(numOfBits1 == numOfBits2){ //if number of set bits are same, then sorting the elements according to magnitude of element (greater/smaller element)
return a < b;
}
return (numOfBits1 < numOfBits2); //if number of set bits are not same, then sorting the elements according to number of set bits in element
}
class Solution {
public:
vector<int> sortByBits(vector<int>& arr) {
sort(arr.begin(),arr.end(), sortBits);
return arr;
}
};
我假设 OP 只是在学习,因此摆弄各种数据结构等可以具有一定的教育价值。尽管如此,只有一条评论指出问题的开始方法是错误的,练习的重点是找到一种比较数字的自定义方法,首先按位数,然后按值。
提供 std::sort
是允许的(OP 使用它),我想整个解决方案在概念上归结为 sth likes this(但我没有用 LeetCode 验证它):
template <typename T>
struct Comp
{
std::size_t countBits(T number) const
{
size_t count;
while(number) {
count += number & 1;
number>>=1;
}
return count;
}
bool operator()(T lhs, T rhs) const
{
/*
auto lb{countBits(lhs)};
auto rb{countBits(rhs)};
return lb==rb ? lhs < rhs : lb < rb;
* The code above is the manual implementation of the line below
* that utilizes the standard library
*/
return std::tuple{countBits(lhs), lhs} < std::tuple{countBits(rhs), rhs};
}
};
class Solution {
public:
void sortByBits(vector<int>& arr) {
std::sort(begin(arr), end(arr), Comp<int>{});
}
};
可能还可以进一步改进,但我会把它作为分析的起点。
该问题已经过评估,并且已经解释了修复方法。
我想给出2个additional/alternative个解决方案。
(像我这样的老人和头发花白的人还会在《Hackers Delight》一书中找到另外 5 个最有效的解决方案)
两种变体都导致使用 std::sort
和 lambda 的单语句解决方案。
请看:
#include <algorithm>
#include <vector>
#include <iostream>
#include <bitset>
// Solution
class Solution {
public:
std::vector<int> sortByBits(std::vector<int>& arr) {
std::sort(arr.begin(), arr.end(), [](const unsigned int i1, const unsigned int i2)
{ size_t c1{ std::bitset<14>(i1).count() }, c2{ std::bitset<14>(i2).count() }; return c1 == c2 ? i1 < i2 : c1 < c2; });
//{ int c1=std::popcount(i1), c2=std::popcount(i2); return c1 == c2 ? i1 < i2 : c1 < c2; });
return arr;
}
};
// Test
int main() {
std::vector<std::vector<int>> testData{
{0,1,2,3,4,5,6,7,8},
{1024,512,256,128,64,32,16,8,4,2,1}
};
Solution s;
for (std::vector<int>& test : testData) {
for (const int i : s.sortByBits(test)) std::cout << i << ' ';
std::cout << '\n';
}
}