日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

程序员面试金典 - 面试题 05.04. 下一个数(线性扫描)

發(fā)布時(shí)間:2024/7/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 程序员面试金典 - 面试题 05.04. 下一个数(线性扫描) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1. 題目
    • 2. 解題
      • 2.1 STL
      • 2.2 線性掃描
      • 2.3 位運(yùn)算

1. 題目

下一個(gè)數(shù)。給定一個(gè)正整數(shù),找出與其二進(jìn)制表達(dá)式中1的個(gè)數(shù)相同大小最接近的那兩個(gè)數(shù)(一個(gè)略大,一個(gè)略小)。

1:輸入:num = 2(或者0b10)輸出:[4, 1] 或者([0b100, 0b1])例2:輸入:num = 1輸出:[2, -1]提示: num的范圍在[1, 2147483647]之間; 如果找不到前一個(gè)或者后一個(gè)滿足條件的正數(shù),那么輸出 -1

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/closed-number-lcci
著作權(quán)歸領(lǐng)扣網(wǎng)絡(luò)所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系官方授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

2. 解題

  • 類似題目:LeetCode 31. 下一個(gè)排列(線性掃描)

2.1 STL

  • prev_permutation\next_permutation,返回的是 bool 值,會(huì)改變?cè)瓟?shù)組!!!
class Solution { public:vector<int> findClosedNumbers(int num) {vector<int> n(32,0);int i = 31;while(num)//數(shù)字轉(zhuǎn)成二進(jìn)制存在數(shù)組里{n[i--] = num&1;num >>= 1;}vector<int> ans(2,-1);next_permutation(n.begin(),n.end());//會(huì)改變?cè)瓟?shù)組long a = calnum(n);if(0 < a && a <= INT_MAX)ans[0] = a;prev_permutation(n.begin(), n.end());//上面next了一下,這里往回退2步prev_permutation(n.begin(), n.end());a = calnum(n);if(0 < a && a <= INT_MAX)ans[1] = a;return ans;}int calnum(vector<int>& num){long sum = 0;for(int i : num)sum = sum*2+i;return sum;} };

0 ms 6.1 MB

2.2 線性掃描

  • 手寫下一個(gè)排列、前一個(gè)排列
class Solution { public:vector<int> findClosedNumbers(int num) {vector<int> n(32,0);int i = 31;while(num){n[i--] = num&1;num >>= 1;}vector<int> ans(2,-1);next_perm(n);long a = calnum(n);if(0 < a && a <= INT_MAX)ans[0] = a;prev_perm(n);prev_perm(n);a = calnum(n);if(0 < a && a <= INT_MAX)ans[1] = a;return ans;}void next_perm(vector<int>& n){int i = n.size()-2, j;while(i>=0 && n[i] >= n[i+1])i--;//找到下降點(diǎn)if(i>=0){j = i+1;while(j < n.size() && n[i] < n[j])j++;swap(n[i],n[j-1]);}reverse(n,i+1,n.size()-1);}void prev_perm(vector<int>& n){int i = n.size()-2, j;while(i>=0 && n[i] <= n[i+1])i--;//找到上升點(diǎn)if(i>=0){j = i+1;while(j < n.size() && n[i] > n[j])j++;swap(n[i],n[j-1]);}reverse(n,i+1,n.size()-1);}void reverse(vector<int>& n, int l ,int r){while(l < r)swap(n[l++],n[r--]);}int calnum(vector<int>& num){ //計(jì)算排列后的數(shù)值long sum = 0;for(int i : num)sum = (sum<<1)+i;return sum;} };

4 ms 6.3 MB

2.3 位運(yùn)算

  • bitset 存儲(chǔ)各個(gè)位,注意 bitset 的位置是反的【0—n-1】對(duì)應(yīng)【低位,。。。高位】
  • 一個(gè)排列從低往高找下降點(diǎn),即找到 01–>10,高位變大,后面的低位變成[000… 111]最小
  • 一個(gè)排列從低往高找上升點(diǎn),即找到 10–>01,高位變小,后面的低位變成[111… 000]最大
class Solution { public:vector<int> findClosedNumbers(int num) {bitset<32> big(num);bitset<32> small(num);vector<int> ans(2,-1);int i, l, r;for(i = 1; i < 32; ++i)//next 找下降點(diǎn){if(big[i-1] > big[i]){big.flip(i);big.flip(i-1);l = 0, r = i-1;while(l < r){while(l < r && big[l]==1)//高位的1全部挪到低位l++;while(l < r && big[r]==0)r--;big.flip(l++);big.flip(r--);}long a = big.to_ulong();if(a <= INT_MAX)ans[0] = a;break;}}for(i = 1; i < 32; ++i)//prev 找上升點(diǎn){if(small[i-1] < small[i]){small.flip(i);small.flip(i-1);l = 0, r = i-1;while(l < r){while(l < r && small[l]==0)//低位的1全部挪到高位l++;while(l < r && small[r]==1)r--;small.flip(l++);small.flip(r--);}long a = small.to_ulong();if(a <= INT_MAX)ans[1] = a;break;}}return ans;} };

總結(jié)

以上是生活随笔為你收集整理的程序员面试金典 - 面试题 05.04. 下一个数(线性扫描)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。