LeetCode031 Next Permutation

详细见:leetcode.com/problems/next-permutation


Java Solution: github

package leetcode;

import java.util.Arrays;

public class P031_NextPermutation {

	/*
	 * 2 ms 11.25%
	 */
	static class Solution1 {
		public void nextPermutation(int[] nums) {
			int len = 0, index = 0, nixu = -1, i = 0, temp = 0;
			if (nums == null || (len = nums.length) < 2)
				return;
			if (nums[len - 1] > nums[len - 2]) {
				swap(nums, len - 1, len - 2);
				return;
			}
			for (index = len - 1; index != 0; index--) {
				if (nums[index - 1] < nums[index]) {
					nixu = index - 1;
					break;
				}
			}
			if (index == 0) {
				for (i = 0; i != len >>> 1; i++)
					swap(nums, i, len - 1 - i);
			} else {
				int swapIndex = binaryIndex(nums, nixu + 1, nums.length - 1, nums[nixu]);
				swap(nums, swapIndex, nixu);
				temp = nixu + nums.length + 1;
				i = (temp & 0x1) == 1 ? temp >> 1 : (temp >> 1) - 1;
				for (; i != nixu; i--)
					swap(nums, i, temp - 1 - i);
			}
		}

		private void swap(int[] nums, int i, int j) {
			int temp = nums[i];
			nums[i] = nums[j];
			nums[j] = temp;
		}

		/*
		 * 保证 [sti, eni]上面arr是逆序的。 val < arr[sti] 找到第一个大于val的对应index
		 */
		int binaryIndex(int[] arr, int sti, int eni, int val) {
			while (sti < eni) {
				int temp = sti + eni, mid = (temp & 0x1) == 0 ? temp >> 1 : (temp >> 1) + 1;
				if (arr[mid] <= val) {
					eni = mid - 1;
				} else {
					sti = mid;
				}
			}
			return eni;
		}
	}
	
	/**
	 * @auther      zxwtry
	 * @email       zxwtry@qq.com
	 * @project     OJ
	 * @package     leetcode
	 * @file        P031_NextPermutation.java
	 * @type        Solution2
	 * @date        2016年11月22日 下午1:45:03
	 * @details     AC 94.65%
	 */
	static class Solution2 {
		public void nextPermutation(int[] arr) {
			if (arr == null || arr.length < 2)	return;
			int i2 = arr.length - 2;
			for (; i2 > -1 && arr[i2] >= arr[i2 + 1]; i2--) {}
			if (i2 == -1) {
				Arrays.sort(arr);
			} else {
				swap(arr, i2, nextPermutation_getLittleBigger(arr, i2));
				reverse(arr, i2 + 1, arr.length - 1);
			}
		}
		private int nextPermutation_getLittleBigger(int[] arr, int i2) {
			int sti = i2 + 1, eni = arr.length - 1, mid = 0;
			while (sti < eni) {
				mid = (sti + eni + 1) / 2;
				if (arr[mid] > arr[i2]) {
					sti = mid;
				} else {
					eni = mid - 1; 
				}
			}
			return sti;
		}
		private void swap(int[] arr, int i, int j) {
			int temp = arr[i];
			arr[i] = arr[j];
			arr[j] = temp;
		}
		private void reverse(int[] arr, int i, int j) {
			while (i < j)	swap(arr, i ++, j --);
		}
	}
}


C Solution: github

/*
    url: leetcode.com/problems/next-permutation/
    9ms 22.22%
*/

#include <stdio.h>
#include <stdlib.h>

void print_array(int * n, int ns) {
    int i = 0;
    for (i = 0; i < ns; i ++)
        printf("%d ", n[i]);
    printf("\r\n");
}

void swap(int * a, int * b) {
    int t = * a;
    * a = * b;
    * b = t;
}

//[i, j)
void reverse(int * n, int i, int j) {
    j --;
    while (i < j) swap(n + (i ++), n + (j --));
}

//[i, j)
int _binary_search_little_bigger(int * n, int i, int j, int v) {
    int m = 0;
    j --;
    while (i < j) {
        //same with (i + j + 1) / 2
        m = i + (j - i + 1) / 2;
        if (n[m] > v) {
            i = m;
        } else {
            j = m - 1;
        }
    }
    return i;
}

void nextPermutation(int* n, int ns) {
    int i = 0, j = 0;
    for (i = ns - 2; i > -1 && n[i] >= n[i + 1]; i --) {};
    if (i == -1) {
        reverse(n, 0, ns);
    } else {
        swap(n + i, n + _binary_search_little_bigger(n, i + 1, ns, n[i]));
        reverse(n, i + 1, ns);
    }
}

int main() {
    int n[] = {3, 4, 3, 2, 1};
    int ns = 5;
    nextPermutation(n, ns);
    print_array(n, ns);
    return 0;
}


Python Solution: github

#coding=utf-8

'''
    url: leetcode.com/problems/next-permutation/
    @author:     zxwtry
    @email:      zxwtry@qq.com
    @date:       2017年4月1日
    @details:    Solution: 95ms 11.05%
'''

class Solution(object):
    #[i, j)
    def decreaseFirstLarger(self, n, i, j, v):
        j -= 1
        while i < j:
            m = (i + j + 1) // 2
            if n[m] > v:
                i = m
            else:
                j = m - 1
        return j
    
    def swap(self, n, i, j):
        t = n[i]
        n[i] = n[j]
        n[j] = t
    
    #[i, j)
    def reverse(self, n, i, j):
        j -= 1
        while i < j:
            self.swap(n, i, j)
            i += 1
            j -= 1
    
    def nextPermutation(self, n):
        """
        :type n: List[int]
        :rtype: void Do not return anything, modify nums in-place instead.
        """
        nn = 0 if n == None else len(n)
        #return short n
        if nn < 2: return
        #find decrease sub list [i, nn - 1]
        i = nn - 1
        while i > 0 and n[i - 1] >= n[i]:
            i -= 1
        #[0, nn - 1] is decrease sub list
        if i == 0:
            n.reverse()
            return
        self.swap(n, i - 1, self.decreaseFirstLarger(n, i, nn, n[i - 1]))
        self.reverse(n, i, nn)

if __name__ == "__main__":
    n = [2, 5, 1, 1]
    Solution().nextPermutation(n)
    print(" %d" * len(n) % tuple(n))
        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值