惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
A
About on SuperTechFans
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
Microsoft Security Blog
Microsoft Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
博客园 - Franky
D
Docker
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
Last Week in AI
Last Week in AI
U
Unit 42
F
Fortinet All Blogs
H
Help Net Security
Blog — PlanetScale
Blog — PlanetScale
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
P
Proofpoint News Feed
月光博客
月光博客
G
Google Developers Blog

博客园 - Grandyang

[LeetCode] 1375. Number of Times Binary String Is Prefix-Aligned 二进制字符串前缀一致的次数 [LeetCode] 1374. Generate a String With Characters That Have Odd Counts 生成每种字符都是奇数个的字符串 [LeetCode] 1373. Maximum Sum BST in Binary Tree 二叉搜索子树的最大键值和 [LeetCode] 1372. Longest ZigZag Path in a Binary Tree 二叉树中的最长交错路径 [LeetCode] 1371. Find the Longest Substring Containing Vowels in Even Counts 每个元音包含偶数次的最长子字符串 [LeetCode] 1370. Increasing Decreasing String 上升下降字符串 [LeetCode] 1368. Minimum Cost to Make at Least One Valid Path in a Grid 使网格图至少有一条有效路径的最小代价 [LeetCode] 1367. Linked List in Binary Tree 二叉树中的链表 [LeetCode] 1366. Rank Teams by Votes 通过投票对团队排名 [LeetCode] 1365. How Many Numbers Are Smaller Than the Current Number 有多少小于当前数字的数字 [LeetCode] 1363. Largest Multiple of Three 形成三的最大倍数 [LeetCode] 1362. Closest Divisors 最接近的因数 [LeetCode] 1361. Validate Binary Tree Nodes 验证二叉树 [LeetCode] 1360. Number of Days Between Two Dates 日期之间隔几天 [LeetCode] 1359. Count All Valid Pickup and Delivery Options 有效的快递序列数目 [LeetCode] 1358. Number of Substrings Containing All Three Characters 包含所有三种字符的子字符串数目 [LeetCode] 1357. Apply Discount Every n Orders 每隔n个顾客打折 [LeetCode] 1354. Construct Target Array With Multiple Sums 多次求和构造目标数组 [LeetCode] 1353. Maximum Number of Events That Can Be Attended 最多可以参加的会议数目 [LeetCode] 1352. Product of the Last K Numbers 最后 K 个数的乘积 [LeetCode] 1351. Count Negative Numbers in a Sorted Matrix 统计有序矩阵中的负数 [LeetCode] 1349. Maximum Students Taking Exam 参加考试的最大学生数
[LeetCode] 1356. Sort Integers by The Number of 1 Bits 根...
Grandyang · 2023-10-22 · via 博客园 - Grandyang

You are given an integer array arr. Sort the integers in the array in ascending order by the number of 1's in their binary representation and in case of two or more integers have the same number of 1's you have to sort them in ascending order.

Return the array after sorting it.

Example 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]

Example 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.

Constraints:

  • 1 <= arr.length <= 500
  • 0 <= arr[i] <= 104

这道题给了一个数组 arr,让我们给数组中的数字排序,按照数字的二进制表示中的1的个数从少到多排序,如果1的个数相同,则按照数字从小到大排。其实主要就是考察了一个求数字的二进制表示中的1的个数,计算方法是用个 while 循环,每次通过'与'上1来得到最低位上的数字,如果得到1,则计数器自增1,然后将数字向右平移一位。知道了如何统计1的个数,这道题就没啥难度了,这里博主最开始的做法是将统计的个数和原数字本身组成一个数对儿,放入到一个新的数组中,然后对这个新数字进行自定义排序,排序的方法是首先按1的个数从小到大排,若个数相等,则按原数字从小到大排。最后只需要按顺序从排序后的数组中提取原数字加入到结果 res 中即可,参见代码如下:

解法一:

class Solution {
public:
    vector<int> sortByBits(vector<int>& arr) {
        vector<int> res;
        vector<vector<int>> nums;
        for (int num : arr) {
            int cnt = 0, d = num;
            while (d > 0) {
                cnt += d & 1;
                d >>= 1;
            }
            nums.push_back({cnt, num});
        }
        sort(nums.begin(), nums.end(), [](vector<int> &a, vector<int> &b) {
            return a[0] < b[0] || (a[0] == b[0] && a[1] < b[1]);
        });
        for (auto &a : nums) {
            res.push_back(a[1]);
        }
        return res;
    }
};

再来看一种写法,这里就主要是把自定义排序方式,和统计1的个数都拆分成了单独的子函数,还有就是统计1的个数的时候和前面的解法稍有些不同。这里采用的是 num & (num - 1),这个操作实际上是快速移除右起第一个1的方法,可以举个例子来看,比如 101 & 100 = 100 这里的 101 就变成了 100,最右边的1被移除了。或者 1100 & 1011 = 1000,1100 变成了 1000,右起第一个1被移除了,这样的话每次操作必定会移除一个1,则计算器可以自增1,循环退出条件也是当数字变为0了退出。这样计算的效率能比之前一位一位检查的高一些,参见代码如下:

解法二:

class Solution {
public:
    vector<int> sortByBits(vector<int>& arr) {
        sort(arr.begin(), arr.end(), compare);
        return arr;
    }
    static bool compare(int a, int b) {
        int cntA = cntOne(a), cntB = cntOne(b);
        return cntA == cntB ? (a < b) : (cntA < cntB);
    }
    static int cntOne(int num) {
        int cnt = 0;
        while (num > 0) {
            num = num & (num - 1);
            ++cnt;
        }
        return cnt;
    }
};

再来看一种利用 C++ 自带统计1的个数的方法,用到了 __builtin_popcount 这个函数,当然如果面试中你这么玩的话,估计过不了,只是放上来秀一下而已,大家还是老老实实用前面的解法吧,参见代码如下:

解法三:

class Solution {
public:
    vector<int> sortByBits(vector<int>& arr) {
        sort(arr.begin(), arr.end(), [](int &a, int &b) {
            int cntA = __builtin_popcount(a), cntB = __builtin_popcount(b);
            return cntA == cntB ? (a < b) : (cntA < cntB);
        });
        return arr;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/1355

类似题目:

Find Subsequence of Length K With the Largest Sum

参考资料:

https://leetcode.com/problems/sort-integers-by-the-number-of-1-bits/

https://leetcode.com/problems/sort-integers-by-the-number-of-1-bits/solutions/758095/cpp-simple-solution-using-self-defined-comparator/

https://leetcode.com/problems/sort-integers-by-the-number-of-1-bits/solutions/517017/c-in-place-sort-popcount/

LeetCode All in One 题目讲解汇总(持续更新中...)