leetcode算法题学习Java版(2)

283.Move Zeros(移动零)

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

class Solution {
   
    public void moveZeroes(int[] nums) {
   
    int k = 0;
        for(int i = 0;i<nums.length;i++){
   
            if(nums[i]!=0){
   
                if(i!=k){
   
                    int temp = nums[k];
                    nums[k] = nums[i];
                    nums[i] = temp;
                }
                k++;
            }
        }
    }
}

75.Sort Colors(颜色分类)

给定一个包含红色、白色和蓝色,一共 *n *个元素的数组,**原地**对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:
不能使用代码库中的排序函数来解决这道题。

示例:
输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]
进阶:

  • 一个直观的解决方案是使用计数排序的两趟扫描算法。
    首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
  • 你能想出一个仅使用常数空间的一趟扫描算法吗?

解题思路,本题共三个元素,非常适合三路快排的方法,并且仅需扫描数组一遍即可完成排序

class Solution {
   
    public void sortColors(int[] nums) {
   
        int zero = -1;         // nums[0...zero]==0
        int two = nums.length; //nums[two...n-1]==2
        for (int i = 0; i < two;) {
   
            if(nums[i]==0){
   
                int temp = nums[++zero];
                nums[zero] = nums[i];
                nums[i++] = temp;
            }else if(nums[i]==1){
   
                i++;
            }else{
   
                assert nums[i]==2;
                int temp = nums[--two];
                nums[two] = nums[i];
                nums[i] = temp;
            }
        }
    }
}

88.Merged sorted Array(合并有序数组)

给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:

输入:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3
输出: [1,2,2,3,5,6]

解题思路:这道题解决很简单,但是最大效率的算法却也比较难想,很巧妙,暴力解法就是把两个数组合并,然后快排。但是参照了leetcode上别人的代码,效率更高,思路就是不断比较二者的最大值,把最大值放在nums1数组的最后,知道排序成功。

class Solution {
   
    public void merge(int[] nums1, int m, int[] nums2, int n) {
   
        int count = m + n - 1;
        m--;
        n--;
        while (m != -1 && n != -1) {
   
            nums1[count--] = nums1[m] > nums2[n] ? nums1[m--] : nums2[n--];
        }
        while (n != -1) {
   
            nums1[count--] = nums2[n--];
        }
    }
}

215.Kth Largest Element in an Array(数组中第K个最大的元素)

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:

你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。

这道题很有趣,他的解法非常多,我也是在这道题感受到了自己与大佬之间的差距,就算用同一种解法,别人的代码也比我写的优雅的多。令人哭笑不得的是,自己写了半天的算法,其实运行下来比别人两行代码(Array.sort,调用jdk内置的函数)就搞定了还慢了很多倍。
解题思路:这道题用简单暴力的解法是非常容易的,同样是先对数组进行排序,最简单的办法是用jdk内置的Array.sort进行排序,然后从后往前取第k个元素,这种解法既简单,又由于jdk内置的快排效率非常高,在leetcode上这种解法只用了4ms,排名第二。当然更聪明的解法很多,例如,使用快排(分治算法),在快排的每一趟排完后,如果要找的k较大,则只对对应的一半继续进行快排,直到找到结果。还有使用堆的办法。

class Solution {
   
    public int findKthLargest(int[] nums, int k) {
   
        Queue<Integer> queue = new PriorityQueue<Integer>();
    for (int i = 0; i < nums.length; i++) {
   
      if (i < k) {
   
        queue.add(nums[i]);
      } else if (queue.peek() < nums[i]) {
   
        queue.remove();
        queue.add(nums[i]);
      }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值