描述
给定一个旋转排序数组,在原地恢复其排序。
说明
什么是旋转数组?
- 比如,原始数组为[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)); } }