zoukankan      html  css  js  c++  java
  • 31. Next Permutation(中等,搞清楚啥是 next permutation)

    Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

    If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

    The replacement must be in-place, do not allocate extra memory.

    Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

    1,2,3 → 1,3,2
    3,2,1 → 1,2,3
    1,1,5 → 1,5,1
    

    这题我看了半天都没搞懂啥是"下一个排列(next permutation)".找了些资料(http://www.geeksforgeeks.org/find-next-greater-number-set-digits/),才了解啥叫 next permutation.
    这么弄:
    假设 A = [2 1 8 7 6 5], 它的 next permutation 咋求? 这样求:

    1. 从右往左,5 6 7 8 都是增序,突然 1 降下来了, 那就所定 1;
    2. 1 右边有 8 7 6 5, 找比1大的但却是这四个数中较小的那个数, 就是 5 喽;
    3. 交换 1 和 5, 结果是 A = [2 5 8 7 6 1];
    4. 然后 对 [8 7 6 1] 增序排序. 最后返回 A = [2 5 1 6 7 8].

    打完,收功!
    这么做就能得到某序列的所谓的 next permutation 了?
    是的!
    为啥?
    没为啥,遍个程序实现它就完事了!

    题目要求中有个特殊情况,就是当 A = [4 3 2 1] 时,返回 A = [1 2 3 4].
    以上就是本题的全部解释了.
    更加详细的考虑及设置,在我的代码注释中写的很清楚.

    人家想法,自个代码:
    有个 cpp 副产品: reverse(A.begin() + start, A.end());
    这个 start 是 A = [2 1 8 7 6 5] 中元素 8 的 index, start = 2.
    (O(n)) time, (O(1)) extra space.
    严格来说,里面用到了排序,就不是(O(n)) time 了.

    // e.g.
    // A = [2 1 8 7 6 5]
    // step 1: from right to left, seek element '1';
    // step 2: from right to left, seek '5' and swap(A[1], A[5])
    //  --- After step 2, A = [2 1 8 7 6 5] --> A = [2 5 8 7 6 1]
    // step 3: reverse(A.begin() + 2, A.end())
    //  --- return A = [2 5 1 6 7 8]
    
    // special case: A = [4 3 2 1] --> will return A = [1 2 3 4]
    
    void nextPermutation(vector<int>& A) {
    	const int n = A.size();
    	if (n == 0 || n == 1)
    		return; //special case
    
    	int start;
    
    	// 4 3 2 1, can not found A[i]<A[i+1]
    	bool found = false;
    
    	// step 1
    	for (int i = n - 2; i >= 0; i--) {
    		if (A[i] < A[i + 1]) {
    			start = i + 1;
    			found = true; // found the case A[i]<A[i+1]
    			break;
    		}
    	}
    
    	// special case
    	// 4 3 2 1 --> return 1 2 3 4 directly
    	if (found == false) {
    		reverse(A.begin(), A.end());
    		return;
    	}
    
    	// step 2
    	for (int j = n - 1; j >= start; j--) {
    		if (A[j] > A[start - 1]) {
    			swap(A[j], A[start - 1]);
    			break;
    		}
    	}
    
    	// step 3
    	reverse(A.begin() + start, A.end());
    
    	return;
    }
    
  • 相关阅读:
    两台oracle数据库相互导数据(转载)
    resin之jvm优化
    求一表中每一个类别共有几条记录数
    jQuery+Ajax+Struts2.0
    改进nginx访问resin的性能
    通过web修改squid用户上网密码
    jvm优化
    Samba通过ad域进行认证并限制空间大小
    Samba 与squid 都可以统一使用域(AD)验证
    ASP.NET 下载文件
  • 原文地址:https://www.cnblogs.com/ZhongliangXiang/p/7500782.html
Copyright © 2011-2022 走看看