今天面試摩拜單車遇到一道演算法題,題目如下:
給定乙個正整數範圍(m,n),返回乙個陣列,該陣列是每個正整數轉換為相應二進位制之後包含1的個數
示例
給定 (1,5) ,
1的二進位制位1,二進位制表示中包含位1的個數字1,
2的二進位制位10,二進位制表示中包含位1的個數字1,
3的二進位制為11,二進位制表示中包含位1的個數字2,
4的二進位制位100,二進位制表示中包含位1的個數字1,
5的二進位制位101,二進位制表示中包含位1的個數字2,
所以返回陣列 [1,1,2,1,2]
這道題有點像leetcode上位1的個數
這道題目。
那麼怎麼解決呢?
最簡單的方法就是,求出每乙個數二進位制中位1的個數,拼成乙個陣列,那麼如何求出正整數中二進位制位1的個數呢?
重點就是求每個數的位1的個數。
這裡就要用到位運算了。大家初中高中或者大學學計算機基礎的時候應該都學過基礎位運算,也就是與
,或
,非
的運算。(還有一些比較複雜的,例如異或
,與非
等組合位運算)
**如下:
public static int numberofone(int n)
return count;
}
我們不斷把數字最後乙個1
反轉,並把答案加一。當數字變成0
的時候偶,我們就知道它沒有1
的位了,此時返回答案。
這裡關鍵的想法是對於任意數字n
,將n
和n-1
做與運算,會把最後乙個1
的位變成0
。為什麼?考慮n
和n−1
的二進位制表示。
我們來詳細解讀一下n & (n - 1)
假設n=5
,n & (n - 1)
就是5&4
,轉換為二進位制就是101&100=100
假設n=4
,n & (n - 1)
就是4&3
,轉換為二進位制就是100&011=000
可以看到,每一次n&(n-1)
的操作就會把n中的位1減少一位,為什麼呢?因為二進位制,無論數字是多少,在二進位制運算中,只要做了-1的操作,就會改變最後一位的值,1變為0或者0變為1.
1變為0就是上面1
的情況,
0變為1就是上面2
的情況。
可以發現,由於每次- 1
操作都會帶了位的變化,所以每次n&n-1
,都會把二進位制中最後的一位1
消除掉,比如101&100=100
,消除了101
最後的1變為100
,100&011=000
,消除了100
最後的1
,也是惟一的1變為000
。所以,當我們不斷把n&=n-1
,直到n=0
的時候,n中的位1就被完全消除了,這個操作做了幾次,也就代表n轉換為二進位制,其中位1的個數有幾個。
看到這裡,這道題最重要的問題就解決了,剩下的工作就是寫個for迴圈將每位數的結果封裝成乙個陣列就行了,for迴圈很簡單,這裡就不再贅述了。
一道演算法題
兩個燒杯,乙個放糖乙個放鹽,用勺子舀一勺糖到鹽,攪拌均勻,然後舀一勺混合 物會放糖的燒杯,問你兩個燒杯哪個雜質多?一樣多吧 對的 為啥?是不是因為 糖和鹽本來就是均勻的 因為,就算不攪拌均,你放一勺過去,那邊放一勺不含雜質的過來,那麼都是一勺雜之 如果攪拌均勻的話也是一樣 小依 21 45 32 也...
一道演算法題
1.上午主要做了對翻譯任務的劃分,下午把 翻譯完畢。2.明天要講的演算法題 對乙個集合,求出其連續元素組成的子集中,和最大的子集 我對這道題的理解是 1 若集合中最小值大於0,意味著所有的都大於0,則最大的子集和,為所有值加起來 2 若集合中最大值小於0,意味著所有的都小於0,則最大的子集和,為集合...
一道演算法題
include using namespace std const int size 5 int max sub array const int a,int n,int m int max matrix const int a size int row,int col,int subsize int...