本文后续将更新解题思路以及优化解题方法
46. 全排列
难度中等
给定一个 没有重复 数字的序列,返回其所有可能的全排列。
示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]
class Solution {
public List> permute(int[] nums) {
LinkedList> list = new LinkedList<>();
permutation(list, nums, 0);
return list;
}
public void permutation(LinkedList> list, int[] nums, int n) {
if (n == nums.length) {
List l = new LinkedList<>();
for (int c : nums) {
l.add(c);
}
list.add(l);
} else {
for (int i = n; i < nums.length; i++) {
swap(nums, i, n);
permutation(list, nums, n + 1);
swap(nums, i, n);
}
}
}
public static void swap(int[] nums, int i, int n) {
int temp = nums[n];
nums[n] = nums[i];
nums[i] = temp;
}
}
47. 全排列 II
难度中等
给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
class Solution {
public List> permuteUnique(int[] nums) {
ArrayList> list = new ArrayList<>();
permutation(list, nums, 0);
return list;
}
public void permutation(List> list,int[] nums,int n){
if(n==nums.length){
List l = new ArrayList<>();
for(int i:nums){
l.add(i);
}
if(!list.contains(l)){
list.add(l);
}
}else{
for (int i = n; i < nums.length; i++) {
swap(nums, i, n);
permutation(list, nums, n + 1);
swap(nums, i, n);
}
}
}
public void swap(int[] nums, int i, int n) {
int temp = nums[n];
nums[n] = nums[i];
nums[i] = temp;
}
}
60. 第k个排列
难度中等
给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。
按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
"123"
"132"
"213"
"231"
"312"
"321"
给定 n 和 k,返回第 k 个排列。
说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。
示例 1:
输入: n = 3, k = 3
输出: "213"
示例 2:
输入: n = 4, k = 9
输出: "2314"
class Solution {
public String getPermutation(int n, int k) {
// n!
int[] nums = new int[n + 1];
nums[0] = 1;
int sum = 1;
for (int i = 1; i < n + 1; i++) {
sum *= i;
nums[i] = sum;
}
// 1-n
ArrayList list = new ArrayList<>();
for (int i = 1; i < n + 1; i++) {
list.add(i);
}
String result = "";
k--;
for (int i = 1; i <= n; i++) {
int index = k / nums[n - i];
result += list.get(index);
list.remove(index);
k = k % nums[n - i];
}
return result;
}
}
31. 下一个排列
难度中等
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
class Solution {
public void nextPermutation(int[] nums) {
int p = -1;
for (int i = nums.length - 1; i >= 1; i--) {
if (nums[i] > nums[i - 1]) {
p = i - 1;
break;
}
}
if (p == -1) {
reverse(nums, 0, nums.length - 1);
return;
}
int q = -1;
for (int i = nums.length - 1; i > p; i--) {
if (nums[i] > nums[p]) {
q = i;
break;
}
}
swap(nums, p, q);
reverse(nums, p + 1, nums.length - 1);
}
public void swap(int[] nums, int i, int j) {
int temp;
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public void reverse(int[] nums, int i, int j) {
while (i < j) {
swap(nums, i, j);
i++;
j--;
}
}
}
78. 子集
难度中等
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
class Solution {
public List> subsets(int[] nums) {
List> result = new ArrayList<>();
for (int i = 1; i <(int)Math.pow(2, nums.length);i++){
char[] chs = toBinary(i, nums.length).toCharArray();
ArrayList l = new ArrayList<>();
for (int j = 0; j < nums.length; j++) {
if (chs[j] == '1') {
l.add(nums[j]);
}
}
result.add(l);
}
result.add(new ArrayList<>());
return result;
}
public String toBinary(int num, int digits) {
String cover = Integer.toBinaryString(1 << digits).substring(1);
String s = Integer.toBinaryString(num);
return s.length() < digits ? cover.substring(s.length()) + s : s;
}
}
90. 子集 II
难度中等
给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。
说明:解集不能包含重复的子集。
示例:
输入: [1,2,2]
输出:
[
[2],
[1],
[1,2,2],
[2,2],
[1,2],
[]
]
class Solution {
public List> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
List> result = new ArrayList<>();
for (int i = 1; i < (int) Math.pow(2, nums.length); i++) {
char[] chs = toBinary(i, nums.length).toCharArray();
ArrayList l = new ArrayList<>();
for (int j = 0; j < nums.length; j++) {
if (chs[j] == '1') {
l.add(nums[j]);
}
}
if (!result.contains(l)) {
result.add(l);
}
}
result.add(new ArrayList<>());
return result;
}
public String toBinary(int num, int digits) {
String cover = Integer.toBinaryString(1 << digits).substring(1);
String s = Integer.toBinaryString(num);
return s.length() < digits ? cover.substring(s.length()) + s : s;
}
}