全排列的另一种实现方法:旋转法
2008-08-22 15:47
429 查看
基本思路如下(以1234为例):
既然说是旋转法,那么它递归的就是旋转
旋转的规则如下:全部左移一位,但最左的移到最右
1234 -> 2341 -> 3412 -> 4123,4位的旋转完成了吧
递归,简单的思路就是从大变小,4位的旋转完成了,就是3位的旋转了,大概过程如下表格
思路清晰了吧
下方即是代码
import java.util.ArrayList;
import java.util.List;
/**
*
* 要点1:递归 + 旋转
* 要点2:n长度的数组,经过n次旋转,会变成原来的数组
*
* @author Daniel You
* @since 2008-8-22
*/
public class Permutation {
// 要排列的数组大小
private int size;
// 要排列的数组
private int[] array;
// 结果集合
private List<int[]> list = new ArrayList<int[]>();
// 构造方法,未做异常处理
// TODO
public Permutation(int[] array) {
this.array = array;
this.size = array.length;
}
// 开始计算的入口点
public void begin() {
this.permutation(size);
}
// 获得结果
public List<int[]> result() {
return list;
}
/**
*
* 这个就是该排列重点,递归
*
* @param newSize
*/
private void permutation(int newSize) {
if (newSize == 1) {
// 如果最后一位了,直接加到结果集了
add();
return;
}
for (int j = 0; j < newSize; j++) {
permutation(newSize - 1);
rotate(newSize);
}
}
// 添加到结果集合
private void add() {
int[] temp = new int[size];
System.arraycopy(array, 0, temp, 0, size);
list.add(temp);
}
/**
* 重点之二:旋转
* @param newSize
*/
private void rotate(int newSize) {
int j;
int position = size - newSize;
int temp = array[position];
for (j = position + 1; j < size; j++) {
array[j - 1] = array[j];
}
array[j - 1] = temp;
}
public static void main(String[] args) {
int[] is = { 1, 2, 3, 4 };
Permutation p = new Permutation(is);
p.begin();
List<int[]> result = p.result();
for(int[] i : result){
p(i);
}
}
// 测试方法,打印一个数据
private static void p(int[] i) {
System.out.printf("%d%d%d%d/n", i[0], i[1], i[2], i[3]);
}
}
既然说是旋转法,那么它递归的就是旋转
旋转的规则如下:全部左移一位,但最左的移到最右
1234 -> 2341 -> 3412 -> 4123,4位的旋转完成了吧
递归,简单的思路就是从大变小,4位的旋转完成了,就是3位的旋转了,大概过程如下表格
四位的旋转 | 第一位不动 后三位的旋转 | 前两位不动 后二位的旋转 | 一位直接返回 | 最终的结果 |
1234 | 234 | 34 | 1234 | 1234 |
43 | 1243 | 1243 | ||
423 | 23 | 1423 | 1423 | |
32 | 1432 | 1432 | ||
342 | 42 | 1342 | 1342 | |
24 | 1324 | 1324 | ||
略 | 略 | 略 | 略 | 略 |
下方即是代码
import java.util.ArrayList;
import java.util.List;
/**
*
* 要点1:递归 + 旋转
* 要点2:n长度的数组,经过n次旋转,会变成原来的数组
*
* @author Daniel You
* @since 2008-8-22
*/
public class Permutation {
// 要排列的数组大小
private int size;
// 要排列的数组
private int[] array;
// 结果集合
private List<int[]> list = new ArrayList<int[]>();
// 构造方法,未做异常处理
// TODO
public Permutation(int[] array) {
this.array = array;
this.size = array.length;
}
// 开始计算的入口点
public void begin() {
this.permutation(size);
}
// 获得结果
public List<int[]> result() {
return list;
}
/**
*
* 这个就是该排列重点,递归
*
* @param newSize
*/
private void permutation(int newSize) {
if (newSize == 1) {
// 如果最后一位了,直接加到结果集了
add();
return;
}
for (int j = 0; j < newSize; j++) {
permutation(newSize - 1);
rotate(newSize);
}
}
// 添加到结果集合
private void add() {
int[] temp = new int[size];
System.arraycopy(array, 0, temp, 0, size);
list.add(temp);
}
/**
* 重点之二:旋转
* @param newSize
*/
private void rotate(int newSize) {
int j;
int position = size - newSize;
int temp = array[position];
for (j = position + 1; j < size; j++) {
array[j - 1] = array[j];
}
array[j - 1] = temp;
}
public static void main(String[] args) {
int[] is = { 1, 2, 3, 4 };
Permutation p = new Permutation(is);
p.begin();
List<int[]> result = p.result();
for(int[] i : result){
p(i);
}
}
// 测试方法,打印一个数据
private static void p(int[] i) {
System.out.printf("%d%d%d%d/n", i[0], i[1], i[2], i[3]);
}
}
相关文章推荐
- 实现全排列的另一种方法(续)
- sharepoint匿名实现的另一种方法
- C#通过yield实现数组全排列的方法
- WINCE--实现屏幕旋转的方法
- Android实现屏幕旋转方法
- 另一种VB图像旋转的方法
- python通过yield实现数组全排列的方法
- 高德地图中根据两点实现旋转图片的方法
- [置顶] C++全排列:一种新的全排列方法(使用单向链表实现)
- 高效率的全排列算法——N进制方法实现
- UIImageView旋转任意角度---实现方法
- Android实现屏幕旋转方法
- 非递归方法用栈实现全排列
- C#实现任意角度旋转图片(方法1)
- Android实现屏幕旋转方法总结
- Swift中实现点击、双击、捏、旋转、拖动、划动、长按手势的类和方法介绍
- 使用递归方法实现全排列
- JS实现图片平面旋转的方法
- python简单实现旋转图片的方法
- Unity通过鼠标或者手势实现拉进拉远,旋转等操作的常用方法