leetcode-338. 比特位计数

338. 比特位计数

class Solution {
    
    /**
     * @param Integer $n
     * @return Integer[]
     */
    function countBits($n) {
        $ret = [0];
        
        for ($i = 1; $i <=$n; $i++) {
            // 上一个数字的比特位数
            $curCount = $ret[$i - 1];
            $curNum = $i - 1;
            
            // 如果
            while ($curNum >= 0) {
                if ($curNum % 2 == 0) {
                    $ret[] = $curCount + 1;
                    break;
                } else {
                    $curCount --;
                    $curNum = floor($curNum / 2);
                }
            }
        }
        return $ret;
    }
}

我的思路是:

  • 前一个值是偶数,那么最后一位必然是 0,当前值的比特位数是前一个加一
  • 前一个值是奇数,那么当前值的比特位数是将后面的 1 全部去掉之后的第一个 0 处加一

官方题解中有三种动态规划题目,可以再研究研究

有一个人的题解比较有意思,找到了规律:
当前是奇数,那么上一个就是偶数,那么偶数加一之后 1 的个数加一
当前值是偶数,那么当前值/2 之后,1 的个数不变

于是就有:

  • 奇数 $ret[] = $ret[$i-1]+1;
  • 偶数 $ret[] = $ret[$i/2];
posted @ 2021-06-14 21:04  吴丹阳-V  阅读(38)  评论(0编辑  收藏  举报