leetcode912 排序数组

给你一个整数数组 nums,请你将该数组升序排列。

  1. //v1.0 未优化的快排
  2. class Solution {
  3. public int[] sortArray(int[] nums) {
  4. int low=0;
  5. int high=nums.length-1;
  6. QSort(nums,low,high);
  7. return nums;
  8. }
  9. public void QSort(int[] nums, int low, int high){
  10. int pivot;
  11. if(low<high){
  12. //将nums一分为二,算出枢轴值pivot
  13. pivot=Partition(nums,low,high);
  14. //对低子表递归排序
  15. QSort(nums,low,pivot-1);
  16. //对高子表递归排序
  17. QSort(nums,pivot+1,high);
  18. }
  19. }
  20. //交换顺序表中子表的记录,使枢轴记录到位,并返回其位置
  21. //此时在它之前(后)的记录均不大于(小)于它
  22. public int Partition(int[] nums,int low,int high){
  23. int pivotKey;
  24. pivotKey=nums[low];
  25. while(low<high){
  26. while(low<high&&nums[high]>=pivotKey) high--;
  27. swap(nums,low,high);
  28. while(low<high&&nums[low]<=pivotKey) low++;
  29. swap(nums,low,high);
  30. }
  31. return low;
  32. }
  33. public void swap(int[] nums, int i, int j){
  34. int temp=nums[j];
  35. nums[j]=nums[i];
  36. nums[i]=temp;
  37. }
  38. }
  39. //v2.0 优化后的快排
  40. class Solution {
  41. public int[] sortArray(int[] nums) {
  42. int low=0;
  43. int high=nums.length-1;
  44. QSort(nums,low,high);
  45. return nums;
  46. }
  47. public void QSort(int[] nums, int low, int high){
  48. int pivot;
  49. while(low<high){
  50. //将nums一分为二,算出枢轴值pivot
  51. pivot=Partition(nums,low,high);
  52. //对低子表递归排序
  53. QSort(nums,low,pivot-1);
  54. //对高子表递归排序
  55. low=pivot+1;
  56. }
  57. }
  58. //交换顺序表中子表的记录,使枢轴记录到位,并返回其位置
  59. //此时在它之前(后)的记录均不大于(小)于它
  60. public int Partition(int[] nums,int low,int high){
  61. int pivotKey;
  62. //优化枢轴选取
  63. int m=low+(high-low)/2;
  64. if(nums[high]<nums[m]) swap(nums,high,m);
  65. if(nums[high]<nums[low]) swap(nums,high,low);
  66. if(nums[low]<nums[m]) swap(nums,low,m);
  67. pivotKey=nums[low];
  68. while(low<high){
  69. while(low<high&&nums[high]>=pivotKey) high--;
  70. nums[low]=nums[high];
  71. while(low<high&&nums[low]<=pivotKey) low++;
  72. nums[high]=nums[low];
  73. }
  74. nums[low] = pivotKey;
  75. return low;
  76. }
  77. public void swap(int[] nums, int i, int j){
  78. int temp=nums[j];
  79. nums[j]=nums[i];
  80. nums[i]=temp;
  81. }
  82. }
  83. class Solution {
  84. public int[] sortArray(int[] nums) {
  85. //堆排序
  86. int i;
  87. for (i = nums.length / 2 - 1; i >= 0; i--) {
  88. HeapAdjust(nums, i, nums.length);
  89. }
  90. for (i = nums.length - 1; i >= 1; i--) {
  91. int temp = nums[i];
  92. nums[i] = nums[0];
  93. nums[0] = temp;
  94. HeapAdjust(nums, 0, i);
  95. }
  96. return nums;
  97. }
  98. public void HeapAdjust(int[] nums, int parent, int length) {
  99. int temp = nums[parent];
  100. int lChild = 2 * parent + 1;
  101. while (lChild < length) {
  102. if (lChild + 1 < length && nums[lChild + 1] > nums[lChild]) lChild++;
  103. if (temp > nums[lChild]) break;
  104. nums[parent] = nums[lChild];
  105. parent = lChild;
  106. lChild = 2 * lChild + 1;
  107. }
  108. nums[parent] = temp;
  109. }
  110. }

剑指51 数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

  1. //利用归并算法(分治思想)
  2. class Solution {
  3. private int count;
  4. public int reversePairs(int[] nums) {
  5. int len = nums.length;
  6. merge(nums,0,len-1);
  7. return count;
  8. }
  9. private void merge(int[] arr, int left, int right){
  10. if(left<right){
  11. int mid = left+((right-left)>>1);
  12. merge(arr,left,mid);
  13. merge(arr,mid+1,right);
  14. mergeSort(arr,left,mid,right);
  15. }
  16. }
  17. private void mergeSort(int[] arr,int left, int mid, int right){
  18. int[] temp = new int[right-left+1];
  19. int index=0;
  20. int temp1 = left;
  21. int temp2 = mid+1;
  22. while(temp1<=mid&&temp2<=right){
  23. if(arr[temp1]<=arr[temp2]){
  24. temp[index++]=arr[temp1++];
  25. }else{
  26. count+=mid-temp1+1; //主要代码
  27. temp[index++]=arr[temp2++];
  28. }
  29. }
  30. if(temp2<=right) System.arraycopy(arr,temp2,temp,index,right-temp2+1);
  31. if(temp1<=mid) System.arraycopy(arr,temp1,temp,index,mid-temp1+1);
  32. System.arraycopy(temp,0,arr,left,right-left+1);
  33. }
  34. }

leetcode493 翻转对

给定一个数组 nums ,如果 i < jnums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。

  1. class Solution {
  2. private int count;
  3. public int reversePairs(int[] nums) {
  4. int len = nums.length;
  5. merge(nums,0,len-1);
  6. return count;
  7. }
  8. private void merge(int[] arr, int left, int right){
  9. if(left<right){
  10. int mid = left+((right-left)>>1);
  11. merge(arr,left,mid);
  12. merge(arr,mid+1,right);
  13. mergeSort(arr,left,mid,right);
  14. }
  15. }
  16. private void mergeSort(int[] arr,int left, int mid, int right){
  17. int[] temp = new int[right-left+1];
  18. int index=0;
  19. int temp1 = left;
  20. int temp2 = mid+1;
  21. //计算翻转对
  22. while(temp1<=mid&&temp2<=right){
  23. if(arr[temp1]>2*(long)arr[temp2]){
  24. count+=mid-temp1+1;
  25. temp2++;
  26. }else{
  27. temp1++;
  28. }
  29. }
  30. //将temp1和temp2复原
  31. temp1=left;
  32. temp2=mid+1;
  33. while(temp1<=mid&&temp2<=right){
  34. if(arr[temp1]<=arr[temp2]){
  35. temp[index++]=arr[temp1++];
  36. }else{
  37. temp[index++]=arr[temp2++];
  38. }
  39. }
  40. if(temp2<=right) System.arraycopy(arr,temp2,temp,index,right-temp2+1);
  41. if(temp1<=mid) System.arraycopy(arr,temp1,temp,index,mid-temp1+1);
  42. System.arraycopy(temp,0,arr,left,right-left+1);
  43. }
  44. }

剑指40 最小的k个数

输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

  1. class Solution {
  2. private static int INSERTION_MAX_VALUE = 7;
  3. private static int K = 0;
  4. public int[] getLeastNumbers(int[] arr, int k) {
  5. K = k;
  6. int low = 0;
  7. int hight = arr.length-1;
  8. quickSort(arr,low,hight);
  9. int[] res = Arrays.copyOfRange(arr,0,k);
  10. return res;
  11. }
  12. public void quickSort(int[] arr, int low, int hight){
  13. int right = hight;
  14. int left = low;
  15. if(right<=left) return;
  16. if((right-left+1)<=7){
  17. insertSort(arr,left,right);
  18. return;
  19. }
  20. int pivot = arr[left];
  21. int i = left+1;
  22. while(i<=right){
  23. if(arr[i]>pivot){
  24. swap(arr,i,right--);
  25. }else if(arr[i]<pivot){
  26. swap(arr,i++,left++);
  27. }else{
  28. i++;
  29. }
  30. }
  31. if(left+1>=K){
  32. quickSort(arr,low,left-1);
  33. }else{
  34. quickSort(arr,low,left-1);
  35. quickSort(arr,left+1,hight);
  36. }
  37. }
  38. public void insertSort(int[] arr, int low, int hight){
  39. for(int m = low+1;m<=hight;m++){
  40. int temp = arr[m];
  41. int n=m-1;
  42. for(;n>=0;n--){
  43. if(arr[n]>temp){
  44. arr[n+1]=arr[n];
  45. continue;
  46. }
  47. break;
  48. }
  49. arr[n+1] = temp;
  50. }
  51. }
  52. public void swap(int[] arr,int i, int j){
  53. int temp = arr[i];
  54. arr[i] = arr[j];
  55. arr[j] = temp;
  56. }
  57. }