描述
给定一个旋转排序数组,在原地恢复其排序。
说明
什么是旋转数组?
- 比如,原始数组为[1,2,3,4], 则其旋转数组可以是[1,2,3,4], [2,3,4,1], [3,4,1,2], [4,1,2,3]
样例
[4, 5, 1, 2, 3]
-> [1, 2, 3, 4, 5]
挑战
使用O(1)的额外空间和O(n)时间复杂度
解决方案:
1、暴力求解法,直接对给定数组进行排序。由于题中规定时间复杂度为o(n),所以此方法不可取
2、三次反转法:
主要思想:
例如 [4, 5, 1, 2, 3] >>[1, 2, 3, 4, 5]
1首先找到最小值的位置地址
2反转最小值前半部分 [4, 5, 1, 2, 3] >> [5, 4, 1, 2, 3]
3反转最小值后半部分 [5, 4, 1, 2, 3] >>[5, 4, 3, 2, 1]
4最后整体反转 [5, 4, 3, 2, 1]>>[1, 2, 3, 4, 5]
java代码实现:
import java.util.ArrayList;
import java.util.List;
public class recoverRotatedSortedArray {
public static List<Integer> rsa(List<Integer> nums) {
int temp = 0;
int min = nums.get(0);
for(int i=0;i<nums.size();i++) {
if(nums.get(i)<min) {
temp = i;
min = nums.get(i);
}
}
System.out.print(min);
reverse(nums,0,temp-1);
reverse(nums,temp,nums.size()-1);
reverse(nums,0,nums.size()-1);
return nums;
}
//字符串反转算法
public static void reverse(List<Integer> nums, int begin, int end) {
float x = begin;
float y = end;
float b = (x+y)/2;
for(int j=begin;j<b;j++) {
int left = nums.get(j);
int right = nums.get(end-j+begin);
nums.set(j, right);
nums.set(end-j+begin, left);
}
}
public static void main(String[] args) {
int[] a = {1, 2, 3, 4,-1};
List<Integer> nums = new ArrayList<Integer>();
for(int k=0;k<a.length;k++) {
nums.add(a[k]);
}
rsa(nums);
System.out.println(rsa(nums));
}
}