1.力扣189
时间复杂度,空间复杂度都是O(N)的暴力法:
class Solution
{
public void rotate(int[] nums, int k)
{
//[1,2] k=3,当k>nums.length的时候,k要取一个模
k=k%nums.length;
//就是将k个后面的数移到最前面去
//比如k=3,就是将最后三个数移到最前面去
int[] result=new int[nums.length];
//将原数组nums后面k个数放到result数组里面
int j=0;
for(int i=nums.length-k;i<nums.length;i++)
{
result[j]=nums[i];
j++;
}
//将原数组nums前面nums.length-k个元素也放到result数组里面
for(int i=0;i<nums.length-k;i++)
{
result[j]=nums[i];
j++;
}
for(int m=0;m<nums.length;m++)
{
nums[m]=result[m];
}
}
}
方法二:三次反转
时间复杂度是O(N),空间复杂度是O(1)
class Solution
{
public void rotate(int[] nums, int k)
{
k=k%nums.length;
//反转后k个数
reverse(nums,nums.length-k,nums.length-1);
//反转前n-k个数
reverse(nums,0,nums.length-k-1);
//整体再进行一次反转
reverse(nums,0,nums.length-1);
}
public void reverse(int[] nums,int left,int right)
{
int length=right-left+1;
while(left<right)
{
int temp=nums[right];
nums[right]=nums[left];
nums[left]=temp;
left++;
right--;
}
}
}
2.力扣33 搜索旋转排序数组
旋转数组其实是本来是一个升序数组,前面小后面大
然后把后面大的拿到前面来,所以最后的局面就是:前面大后面小,区域1最小的数也比区域2最大的数大
第一步是先判断是前半段长还是后半段长的情形
第二步:target处在nums[left]~nums[mid]区间还是nums[mid]~nums[right]区间
如果target处在nums[left]~nums[mid],那就right=mid-1
如果target处在nums[mid]~nums[right],那就left=mid+1
第三步:left=mid+1或者是right=mid-1
class Solution
{
public int search(int[] nums, int target)
{
int left=0;
int right=nums.length-1;
int mid=0;
while(left<=right)
{
mid=(left+right)/2;
if(nums[mid]==target) return mid;
if(nums[left]==target) return left;
if(nums[right]==target) return right;
//后比前大,说明[left,mid]在区域1,说明前半段更长
//target可能处在两个区域nums[left]~nums[mid],或者是nums[mid]~nums[right]
if(nums[left]<nums[mid])
{
//当处在nums[left]~nums[mid]
if(nums[left]<target&&target<nums[mid])
{
right=mid-1;
}
else//如果target处在nums[mid]~nums[right]
{
left=mid+1;
}
}
//前比后大,nums[left]>=nums[mid],说明mid在区域2,后半段更长
//target可能处在两个区域nums[left]~nums[mid],或者是nums[mid]~nums[right]
else
{
if(nums[mid]<target&&target<nums[right])
{
left=mid+1;
}
else
{
right=mid-1;
}
}
}
return -1;
}
}