1、n个数的全排列问题。
代码
public class one {
// 交换函数
public static void swap(char[] array, int i, int j) {
char temp = array[i];
array[i] = array[j];
array[j] = temp;
}
// 全排列函数
public static void fun(char[] array, int p) {
if (p == array.length) { //当前为最后一个元素的排列,及当前序列已经完整
System.out.println(new String(array));
} else { // 进行全排列模拟
for (int i = p; i < array.length; i++) { // 分别确定一种字符串的i到位
swap(array, p, i);
fun(array, p + 1);
swap(array, i, p);
}
}
}
public static void main(String args[]) {
String string = "123";
fun(string.toCharArray(),0);
}
}
输出结果
测试固定序列串 “123” 的全排列结果,共输出对应的6种排列结果。
总结
该算法优点:简洁、容易实现
缺点:没有排序效果。解决办法:可以存储排列后的每一种结果,然后对结果的序列数组进行排序,从而解决没有排序的问题,但是随着待排数组的增长其排序的时间复杂度也会不断上升。故该算法不适合解决长序列的全排列排序问题。
2、在一个给定的n个元素的有序序列中查找出与给定关键字x相同的元素的具体位置。即输入一个n个元素的序列,其中n个元素从小到大的顺序排列,查找是否存在给定的值x.(用二分查找法)。
代码
import java.util.Scanner;
public class two {
public static int BinarySearch(int[] array, int x) {
int l = 0, r = array.length;
// 二分查找
while (l <= r) {
int mid = (l + r) / 2;
if (array[mid] > x) {
r = mid;
l = l + 1;
} else if (array[mid] < x) {
l = mid;
r = r - 1;
}else{ // 找到该元素,返回该元素的位置
return mid+1;
}
}
return -1;
}
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
int n;
n = scanner.nextInt();
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
int x = scanner.nextInt();
int p = BinarySearch(array,x);
System.out.println(p);
}
}
输出结果
测试用例1
输入
6
1 2 3 4 5 6
9
输出(-1代表未找到)
-1
测试用例1
输入
6
1 2 3 4 5 6
5
输出(-1代表未找到)
5
总结
二分搜索中在x值大于中间值的情况下,需要进行l=mid,r=r-1操作;在x值小于中间值的情况下,要进行r=mid,l=l+1的操作;
3、改写二分搜索算法:
设a[0:n-1]是已排好序的数组,请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
代码
import java.util.Scanner;
public class Three {
public static int BinarySearch(int[] array, int x) {
int l = 0, r = array.length;
int mid = -1;
if(x > array[array.length-1]){ //当前x值已经大于所有数组中的元素
return array.length;
}
if(x < array[0]){ //当前x值已经小于所有数组中的元素
return 0;
}
// 二分查找
while (l <= r) {
mid = (l + r) / 2;
if (array[mid] > x) {
r = mid-1;
} else if (array[mid] < x) {
l = mid+1;
} else { // 找到该元素,返回该元素的位置
return mid + 1;
}
}
return mid;
}
public static void main(String args[]) {
Scanner scanner = new Scanner(System.in);
int n;
n = scanner.nextInt();
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
int x = scanner.nextInt();
int p = BinarySearch(array, x);
// System.out.println(p);
if (p!=0&&array[p-1] == x) { //当前是找到该x值
System.out.println("在有序数组中找到该值位置为" + p);
}else{ // 未找到该值
if(p==array.length){ //如果比所有与元素都大则不存在比他大的最小值
System.out.println("在有序数组中未找到该值,但存在比其小的最大元素:"+array[p-1]);
}else if(p==0){ //如果比所有与元素都小则不存在比他大的最小值
System.out.println("在有序数组中未找到该值,但存在比其大的最小元素:" + array[0]);
}else{
System.out.println("在有序数组中未找到该值,但存在比其大的最小元素:" + array[p]+",存在比其大的最小元素:"+array[p-1]);
}
}
}
}
输出结果
总结
二分法关键代码
// 二分查找
int l = 0, r = array.length;
int mid = -1;
while (l <= r) {
mid = (l + r) / 2;
if (array[mid] > x) {
r = mid-1;
} else if (array[mid] < x) {
l = mid+1;
} else { // 找到该元素,返回该元素的位置
return mid + 1;
}
}
return mid;
}