Problem 31 Next Permutation
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place, do not allocate extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
解题思路:
1. 这道题最主要的是要理解题目的意思,是要找到一个 最小的,比当前数大的 数,也就是在找到比当前的数更大的数的集合中的最小值
2. 因为前面的数字是高位,改变会对数值影响更大,所以要找一个较小的更大的数,要首先考虑改变低位的值
3. 从后往前搜索,找到第一个nums[i],使得nums[i] > nums[i-1],然后从后面找一个大于nums[i-1]的最小值,与nums[i-1]交换,然后把i-1后面的数列从小到大排序,即可得到答案
4.特殊情况是数列是一个降序的有序队列,这样该序列就是数字组合的最大值,无法找到更大的值,所以根据题目要求重新排序
代码如下:
public class Solution { public void nextPermutation(int[] nums) { int length = nums.length; int flag = 0; for(int i = length-1;i >0;i--){ if(flag == 1){ break; } if(nums[i] > nums[i -1]){ int min = i; int k = length-1; while(k >= i){ if(nums[k] > nums[i-1] && nums[k] < nums[min]){ min = k; } k--; } swap(nums,i-1,min); flag = 1; quickSort(nums,k+1,length-1); break; } } if(flag == 0){ quickSort(nums,0,length-1); } return; } public void quickSort(int[] nums,int left,int right){ if(left > right){ return; } int i = left; int j = right; int key = nums[i]; while(i < j){ while(i < j && nums[j] >= key){ j--; } if(i < j){ nums[i] = nums[j]; } while(i<j && nums[i] <= key){ i++; } if(i < j){ nums[j] = nums[i]; } } nums[i] = key; quickSort(nums,left,i-1); quickSort(nums,i+1,right); } public void swap(int[] nums,int i, int j){ int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; return; } }
Problem 33 Search in Rotated Sorted Array
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., 0 1 2 4 5 6 7
might become 4 5 6 7 0 1 2
).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
解题思路:
1. 因为数组是轮转的,所以可以考虑为对于数组的某一部分,一定是有序的,所以可以用二分查找的思路
2. 把数组对半分开,有一半一定是有序的,如果target在有序的这一半,即可直接用二分查找找出,如果target在另一半,则继续切分另一半数组,直到找到target或者切完数组为止
代码如下:
public class Solution { public int search(int[] nums, int target) { return binSearch(nums,0,nums.length - 1,target); } public int binSearch(int[] nums,int left,int right,int target){ int mid = (left + right)/2; System.out.println(mid); if(nums.length == 0){ return -1; } if(right <= left){ if(nums[mid] == target){ return mid; } else{ //System.out.println("test0"); return -1; } } if(nums[mid] == target){ return mid; } if(nums[left] <= nums[mid]){ if(target >= nums[left] && target < nums[mid]){ //System.out.println("test1"); return binSearch(nums,left,mid -1,target); } else{ //System.out.println("test2"); return binSearch(nums,mid+1,right,target); } } if(nums[mid] <= nums[right]){ if(target <= nums[right] && target > nums[mid]){ //System.out.println("test3"); return binSearch(nums,mid+1,right,target); } else{ //System.out.println("test4"); return binSearch(nums,left,mid -1,target); } } //System.out.println("test5"); return -1; } }