ゴールデンインタビュープログラマ - フェイス質問05.04次の番号(リニアスイープ)

1.トピック

次の番号。与えられた正の整数をその見つけるために、バイナリでの発現を1と同じ数の大きさの最も近い 2つの数のもの(わずかに大きく、わずかに小さいです)。

1:
 输入:num = 2(或者0b10)
 输出:[4, 1] 或者([0b100, 0b1])
 
例2:
 输入:num = 1
 输出:[2, -1]
 
提示:
num的范围在[1, 2147483647]之间;
如果找不到前一个或者后一个满足条件的正数,那么输出 -1

出典:滞在ボタン(LeetCode)
//leetcode-cn.com/problems/closed-number-lcci:リンク:httpsの
すべてのネットワークからの控除が著作権を保有。商業転載は、ソースを明記してください許可公式、非商用の転載をご連絡ください。

2.問題解決

2.1 STL

  • prev_permutation\next_permutation、戻り値をBOOL、元の配列を変更されます!
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_permutation(n.begin(),n.end());//会改变原数组
    	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リニアスキャン

  • 配置された手書きは、前に配置されています
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--;//找到下降点
    	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--;//找到上升点
    	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)
    {	//计算排列后的数值
    	long sum = 0;
    	for(int i : num)
    		sum = (sum<<1)+i;
    	return sum;
    }
};

4 ms 6.3 MB

公開された822元の記事 ウォンの賞賛1843 ビュー42万+

おすすめ

転載: blog.csdn.net/qq_21201267/article/details/105387418