leetcode75.颜色分类——学习笔记

题目:力扣https://leetcode-cn.com/problems/sort-colors/


class Solution {
    public void sortColors(int[] nums) {
        quickSort(nums,0,nums.length-1);
    }

    private void swap(int[] nums,int index1,int index2){
        nums[index1] ^= nums[index2];
        nums[index2] ^= nums[index1];
        nums[index1] ^= nums[index2];
    }

    private void quickSort(int[] nums,int l,int r){
        if(l >= r){
            return;
        }
        int left = l;
        int right = r;
        int pivot = nums[left];
        while(left < right){
            if(left < right && nums[right] >= pivot){
                right--;
            }
            if(left < right){
                swap(nums,left,right);
            }
            if(left < right && nums[left] <= pivot){
                left++;
            }
            if(left < right){
                swap(nums,left,right);
            }
        }
        quickSort(nums,l,right-1);
        quickSort(nums,left+1,r);
    }
}

 


思路:这是一道很平常的排序题,有种开挂的方法就是直接Arrays.sort(nums)直接解决战斗。当然如果这么提交的话明显对不住“中等”的难度设定,因此我选择了手写。大概思路就是,位运算交换+快速排序。位运算交换属于一种稍稍有点抖机灵的实现方式,今天刚学会顺带用这道题练练手,快速排序之间在leetcode56.合并区间也用过,这里也是大同小异。


1.位运算交换。我们知道加减乘除的底层也是通过位运算来实现的,因此与其相比位运算的效率会占优一些。^这个是抑或运算符,抑或运算的法则:两数相同则结果为1;两数不同则结果为0。因此,我们可以得出两条定律:(1)0^N=N2(2)N^N=0。清楚了这些之后,现在开始举例说明。例如:

int a = 甲;

int b = 乙;

a = a ^ b;    //a = 甲 ^ 乙    b = 乙

b = a ^ b;    //a = 甲 ^ 乙    b = 甲 ^ 乙 ^乙 = 甲

a = a ^ b;    //a = 甲 ^ 乙 ^ 甲 = 乙    b = 甲

这样就完成了通过位运算交换数组中的两个元素。值得一提的是,由于位运算的特点,这种方法适用于两个元素的地址一定是独立的(是地址,不是值,尽管两个元素的值相同也可以正常交换),如果地址相同则会把数据抹去变成0。

private void swap(int[] nums,int index1,int index2){
    nums[index1] ^= nums[index2];
    nums[index2] ^= nums[index1];
    nums[index1] ^= nums[index2];
}

2.快速排序。选定任意数为pivot,然后比对左右指针指向的元素,小于pivot的放左侧,大于pivot的放右侧。通过递归调用的方法,先比对左半部分,再比对右半部分。详细的叙述可以参考之前写过的题目——leetcode56.合并区间

private void quickSort(int[] nums,int l,int r){
    if(l >= r){
        return;
    }
    int left = l;
    int right = r;
    int pivot = nums[left];
    while(left < right){
        if(left < right && nums[right] >= pivot){
            right--;
        }
        if(left < right){
            swap(nums,left,right);
        }
        if(left < right && nums[left] <= pivot){
            left++;
        }
        if(left < right){
            swap(nums,left,right);
        }
    }
    quickSort(nums,l,right-1);
    quickSort(nums,left+1,r);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hokachi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值