快速排序(用i和j双指针,左部分值小,当i=j时,两部分按基准值已经排序好,将基准值放到j即可。
class Solution {
public int[] sortArray(int[] nums) {
sort(nums,0,nums.length-1);
return nums;
}
void sort(int[] nums,int left,int right){
if(left>=right) return;
int p=partition(nums,left,right);
sort(nums,left,p-1);
sort(nums,p+1,right);
}
int partition(int[] nums,int left,int right){
int privot=nums[left];//选第一个为基准值
int i=left+1,j=right;
while(i<=j){
while(i<right&&nums[i]<=privot){// num【i如果小于基准值,i继续遍历
i++;
}
while(j>left&&nums[j]>privot){
j--;
}
if(i>=j) break;
swap(nums,i,j);//跳出循环时,代表num[i]大于privot或 j小于privot
}
swap(nums,left,j);
return j;
}
void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
快速选择算法(快速排序相当于一次只排一个元素在中间,切索引值为p
class Solution {
Random random=new Random();
public int findKthLargest(int[] nums, int k) {
k=nums.length-k;//变为求索引
shuffle(nums);//洗牌算法
int left=0,right=nums.length-1;
while(left<=right){
int p=partition(nums,left,right);
if(k>p){
left=p+1;//对右端的再不断分割 排序
}else if(k<p){
right=p-1;
}else return nums[p];
}
return -1;
}
void shuffle(int[] nums){
for(int i=nums.length-1;i>0;i--){
int j=random.nextInt(i+1);//取i之前的数
swap(nums,i,j);
}
}
int partition(int nums[],int left,int right){
int privot=nums[left];//第一个为基准值
int i=left+1,j=right;
while(i<=j){
while(i<=right&&nums[i]<=privot){
i++;
}
while(j>=left+1&&nums[j]>privot){
j--;
}
if(i>=j) break;
swap(nums,i,j);
}
swap(nums,left,j);
return j;
}
void swap(int[] nums,int i,int j){
int temp=nums[i];
nums[i]=nums[j];
nums[j]=temp;
}
}
最近公共祖先
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
return find(root,p,q);
}
TreeNode find(TreeNode root,TreeNode p,TreeNode q){//用后序遍历找最近公共祖先
if(root==null) return null;
if(root.val==p.val||root.val==q.val){
return root;
}
TreeNode left=find(root.left,p,q);
TreeNode right=find(root.right,p,q);
if(left!=null&&right!=null){
return root;
}
return left==null? right:left;
}
}