LeetCode刷題思路

篇前語:刻意練習是走向卓越的必經之路!
371題:求兩個整數的和,不允許使用+-運算符
7.25思路:除+-外其他運算符沒有限制,如移位,乘除等。首先明確,乘除是不能代替加減運算的,移位是單目運算符,也不適用。因此通過運算符求和可能行不通。其次,調用C語言內置math函數sum本質上依然使用了+-。由此引出一個關鍵問題:在leetcode上能不能使用已有的函數,比如此題,如果設計兩個字符串,其長度分別是兩個整數值,合併字符串後求取其長度相當於間接求和兩個整數。但出題人意圖明顯不在此,猜測答案與數據結構有關。
討論區解決方案:1,初始化一個vector,內有2個int元素a和b,返回accumulate()計算的和。編譯通過。顯然本方案使用了一個stl庫函數accumulate,該函數在numeric頭文件中有定義,accumulate帶三個形參,前兩個指定要累加的元素範圍,第三個是累加初始值,顯然其類型應與vector元素相同。本題中如此調用:accumulate(v.begin(),v.end(),0)。關於accumulate的詳盡分析見http://www.cnblogs.com/heyonggang/p/3241878.html
2,使用位操作符,位操作符有異或^,或 | ,與 & ,移位<<,>>,取反~等6種,實質上計算機內部使用位操作構成加法器,因此此題真正意圖是考察加法器的知識。加法可以看作異或操作+進位的組合,由“位與”+“左移”產生進位中間數,當無進位時中間數爲0。具體代碼如下:

getSum(int a,int b){
    while(b){
        int carry = a & b;
        a ^= b;
        b = carry<<1;
    }
    return a;
}

關於此解決方案的一點思考:位操作符是針對二進制數而言的,對於int型,運算時自動轉化爲16位二進制數。任何位操作結果都不能溢出16位數範圍。

344題:翻轉字符串,如輸入hello,輸出olleh。
7.25思路:考察string類型的使用,s.size()獲取字符串的長度,即字符的個數,返回size_type類型,size_type是string類自定義類型,可轉化爲int型,它實現了“與具體機器無關”,可存儲任意大小的string長度。標準庫許多類型(string,vector,list,deque等)的配套類型及方法命名都是一致的,如size(),begin(),end(),下標讀取元素等。
本題的另一個注意點是避免返回局部變量,因此在解決函數內部定義一個新string用於返回是不合適的,正確的做法是交換首尾元素,代碼如下:

string reverseString(string s){
   int left = 0,right = s.size();
   while(left<right){
       int t = s[left];
       s[left++] = s[right];
       s[right--] = t;
   } 
   return s;
}

338題 統計位數:給定一個非負整數,將從0到該整數間所有整數的二進制位爲1的個數輸出到數組。如給定5,則輸出[0,1,1,2,1,2];
7.27思路,常規做法是不斷對2取餘統計1的個數,時間複雜度爲O(n*sizeof(整數))。但本題要求時間複雜度爲O(n),因此需要找出輸出數組元素與對應下標的關係。推演發現該序列爲:0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,…………
規律爲:當整數爲2^n時,bit1的位數始終是1;整數爲(2^n-1),bit1的位數始終是n;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章