leetcode912 排序数组
给你一个整数数组 nums,请你将该数组升序排列。
//v1.0 未优化的快排class Solution {public int[] sortArray(int[] nums) {int low=0;int high=nums.length-1;QSort(nums,low,high);return nums;}public void QSort(int[] nums, int low, int high){int pivot;if(low<high){//将nums一分为二,算出枢轴值pivotpivot=Partition(nums,low,high);//对低子表递归排序QSort(nums,low,pivot-1);//对高子表递归排序QSort(nums,pivot+1,high);}}//交换顺序表中子表的记录,使枢轴记录到位,并返回其位置//此时在它之前(后)的记录均不大于(小)于它public int Partition(int[] nums,int low,int high){int pivotKey;pivotKey=nums[low];while(low<high){while(low<high&&nums[high]>=pivotKey) high--;swap(nums,low,high);while(low<high&&nums[low]<=pivotKey) low++;swap(nums,low,high);}return low;}public void swap(int[] nums, int i, int j){int temp=nums[j];nums[j]=nums[i];nums[i]=temp;}}//v2.0 优化后的快排class Solution {public int[] sortArray(int[] nums) {int low=0;int high=nums.length-1;QSort(nums,low,high);return nums;}public void QSort(int[] nums, int low, int high){int pivot;while(low<high){//将nums一分为二,算出枢轴值pivotpivot=Partition(nums,low,high);//对低子表递归排序QSort(nums,low,pivot-1);//对高子表递归排序low=pivot+1;}}//交换顺序表中子表的记录,使枢轴记录到位,并返回其位置//此时在它之前(后)的记录均不大于(小)于它public int Partition(int[] nums,int low,int high){int pivotKey;//优化枢轴选取int m=low+(high-low)/2;if(nums[high]<nums[m]) swap(nums,high,m);if(nums[high]<nums[low]) swap(nums,high,low);if(nums[low]<nums[m]) swap(nums,low,m);pivotKey=nums[low];while(low<high){while(low<high&&nums[high]>=pivotKey) high--;nums[low]=nums[high];while(low<high&&nums[low]<=pivotKey) low++;nums[high]=nums[low];}nums[low] = pivotKey;return low;}public void swap(int[] nums, int i, int j){int temp=nums[j];nums[j]=nums[i];nums[i]=temp;}}class Solution {public int[] sortArray(int[] nums) {//堆排序int i;for (i = nums.length / 2 - 1; i >= 0; i--) {HeapAdjust(nums, i, nums.length);}for (i = nums.length - 1; i >= 1; i--) {int temp = nums[i];nums[i] = nums[0];nums[0] = temp;HeapAdjust(nums, 0, i);}return nums;}public void HeapAdjust(int[] nums, int parent, int length) {int temp = nums[parent];int lChild = 2 * parent + 1;while (lChild < length) {if (lChild + 1 < length && nums[lChild + 1] > nums[lChild]) lChild++;if (temp > nums[lChild]) break;nums[parent] = nums[lChild];parent = lChild;lChild = 2 * lChild + 1;}nums[parent] = temp;}}
剑指51 数组中的逆序对
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
//利用归并算法(分治思想)class Solution {private int count;public int reversePairs(int[] nums) {int len = nums.length;merge(nums,0,len-1);return count;}private void merge(int[] arr, int left, int right){if(left<right){int mid = left+((right-left)>>1);merge(arr,left,mid);merge(arr,mid+1,right);mergeSort(arr,left,mid,right);}}private void mergeSort(int[] arr,int left, int mid, int right){int[] temp = new int[right-left+1];int index=0;int temp1 = left;int temp2 = mid+1;while(temp1<=mid&&temp2<=right){if(arr[temp1]<=arr[temp2]){temp[index++]=arr[temp1++];}else{count+=mid-temp1+1; //主要代码temp[index++]=arr[temp2++];}}if(temp2<=right) System.arraycopy(arr,temp2,temp,index,right-temp2+1);if(temp1<=mid) System.arraycopy(arr,temp1,temp,index,mid-temp1+1);System.arraycopy(temp,0,arr,left,right-left+1);}}
leetcode493 翻转对
给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对。
class Solution {private int count;public int reversePairs(int[] nums) {int len = nums.length;merge(nums,0,len-1);return count;}private void merge(int[] arr, int left, int right){if(left<right){int mid = left+((right-left)>>1);merge(arr,left,mid);merge(arr,mid+1,right);mergeSort(arr,left,mid,right);}}private void mergeSort(int[] arr,int left, int mid, int right){int[] temp = new int[right-left+1];int index=0;int temp1 = left;int temp2 = mid+1;//计算翻转对while(temp1<=mid&&temp2<=right){if(arr[temp1]>2*(long)arr[temp2]){count+=mid-temp1+1;temp2++;}else{temp1++;}}//将temp1和temp2复原temp1=left;temp2=mid+1;while(temp1<=mid&&temp2<=right){if(arr[temp1]<=arr[temp2]){temp[index++]=arr[temp1++];}else{temp[index++]=arr[temp2++];}}if(temp2<=right) System.arraycopy(arr,temp2,temp,index,right-temp2+1);if(temp1<=mid) System.arraycopy(arr,temp1,temp,index,mid-temp1+1);System.arraycopy(temp,0,arr,left,right-left+1);}}
剑指40 最小的k个数
输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
class Solution {private static int INSERTION_MAX_VALUE = 7;private static int K = 0;public int[] getLeastNumbers(int[] arr, int k) {K = k;int low = 0;int hight = arr.length-1;quickSort(arr,low,hight);int[] res = Arrays.copyOfRange(arr,0,k);return res;}public void quickSort(int[] arr, int low, int hight){int right = hight;int left = low;if(right<=left) return;if((right-left+1)<=7){insertSort(arr,left,right);return;}int pivot = arr[left];int i = left+1;while(i<=right){if(arr[i]>pivot){swap(arr,i,right--);}else if(arr[i]<pivot){swap(arr,i++,left++);}else{i++;}}if(left+1>=K){quickSort(arr,low,left-1);}else{quickSort(arr,low,left-1);quickSort(arr,left+1,hight);}}public void insertSort(int[] arr, int low, int hight){for(int m = low+1;m<=hight;m++){int temp = arr[m];int n=m-1;for(;n>=0;n--){if(arr[n]>temp){arr[n+1]=arr[n];continue;}break;}arr[n+1] = temp;}}public void swap(int[] arr,int i, int j){int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}
