为了转行程序员而努力的第十八天

今天早起了,是宝贵的周六,随着工作量增大,属于自己的时间越来越少,一天之内被紧急的事情打断了三,四次,要开始做好实在不行脱产准备面试的预期了,现在的积蓄可以坚持一年待业,但是心态肯定很难保持,所以不到万不得已还是不希望失去经济来源,只能咬牙再坚持一段时间了,至少要先把简历准备好。

今日进度:

  1. 网课开始进入难度稍高一点的数组题目,第一次真正使用快速排序的思路解决问题,实现的时候卡住了,参考了一下发现该使用while的地方,使用了if,才发现其实基础的while循环都没有完全理解,while的条件只要为真,就会一直循环下去,在实现快排的时候是非常有用的。
  2. 坚持锻炼,出去走了一大圈,算是不间断的刷题和上班之间的调节
  3. 坚持录声音,有时间可以多录一些小王子
  4. 刷题真的很枯燥,解不出来和修bug的时候也是真的很难受,现在的课程也是刷题为主的,听课和看文档的时间变得非常珍惜了

学习笔记:

  1. leetcode75

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

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

示例 1: 输入:nums = [2,0,2,1,1,0] 输出:[0,0,1,1,2,2]
示例 2: 输入:nums = [2,0,1] 输出:[0,1,2]
示例 3: 输入:nums = [0] 输出:[0]
示例 4: 输入:nums = [1] 输出:[1] 提示:
n == nums.length 1 <= n <= 300 nums[i] 为 0、1 或 2

解题思路有两种:
1.计数排序:分别统计0,1,2的元素个数,再在数组中直接赋值
2.三路快速排序:遍历数组,设置三个指针,zero, i, two,元素值等于1的不变,小于1和大于1的分别放在zero的后一个和two的前一个,时间复杂度为O(N),空间复杂度为O(1)
这里的代码是使用第二种方法实现的

class Solution {
    public void sortColors(int[] nums) {
        int zero = -1;//表示0的结束位置
        int two = nums.length;//表示2的开始位置
        for (int i=0; i<two;){
            if(nums[i] == 1){
                i++;
            }
            else if(nums[i] == 2){
                two--;
                swap(nums, i, two);
            }
            else{
                assert(nums[i] == 0);
                zero++;
                swap(nums, i, zero);
                i++;
            }
        }
    }
    public void swap(int[] n, int a, int b){
        int tmp;
        tmp = n[a];
        n[a] = n[b];
        n[b] = tmp;
    }
}
  1. leetcode 88 合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2中的元素数目。 请你合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。

示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6] 解释:需要合并 [1,2,3] 和 [2,5,6] 。 合并结果是 [1,2,2,3,5,6],其中斜体加粗标注的为 nums1 中的元素。
示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1] 解释:需要合并 [1] 和 [] 。 合并结果是 [1] 。
示例 3:
输入:nums1 = [0], m = 0,nums2 = [1], n = 1
输出:[1] 解释:需要合并的数组是 [] 和 [1] 。 合并结果是 [1] 。 注意,因为 m =0 ,所以 nums1 中没有元素。nums1 中仅存的 0 仅仅是为了确保合并结果可以顺利存放到 nums1 中。

提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m +n <= 200
-10^9 <= nums1[i], nums2[j] <= 10 ^9

解题思路:使用归并排序的思路,创建一个新的数组,分别遍历两个数组的,将较小的插入新数组,如果一个数组遍历结束,另一个数组还有剩余,将剩余部分直接拷贝到新数组中。将新数组的值拷贝给nums1。时间复杂度为O(M+N),空间复杂度为O(M+N)。

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        int[] tmp = new int[m+n];
        int mi=0;
        int ni=0;
        for(int i=0; i<m+n; i++){
            if(mi > m-1 && ni <= n-1){
                for(int j=i; j<m+n; j++){
                    tmp[j] = nums2[ni];
                    ni++;
                }
                break;
            }
            if(ni > n-1 && mi <= m-1){
                for(int j=i; j<m+n; j++){
                    tmp[j] = nums1[mi];
                    mi++;
                }
                break;
            }
            if(nums1[mi] <= nums2[ni]){
                tmp[i] = nums1[mi];
                mi++;
            }
            else{
                tmp[i] = nums2[ni];
                ni++;
            }
        }
        for(int i=0; i<m+n; i++){
            nums1[i] = tmp[i];
        } 
    }
}
  1. leetcode215 数组中的第K个最大元素

给定整数数组 nums 和整数 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
提示: 1 <= k <= nums.length <= 10^4
-10^4 <= nums[i] <= 10 ^4

解题思路:利用快速排序的思路,先找出pivot,第一次排序后,判断K与nums.length-pivot,即pivot是第nums.length-pivot大的元素,如果K小于该值,对pivot右边的数组做递归操作;如果K大于该值,对pivot左边的数组做递归操作,K等于该值,直接返回nums[pivot] 的值。该方法只将数组遍历了一次,时间复杂度为O(N)。

class Solution {
    public int findKthLargest(int[] nums, int k) {
        int result;
        int left = 0;
        int right = nums.length-1;
        result = qc(nums, left, right, k);
        return result;

    }
    public int qc(int[] n, int l, int r, int k){
            int pivot;
            pivot = partition(n, l, r);
            if((n.length - pivot) == k){
                return n[pivot];
            }
            else if((n.length - pivot) > k){
                return qc(n, pivot+1, r, k);
            }
            else{
                return qc(n, l, pivot-1, k);
            }
        }
    public int partition(int[] n, int l , int r){
            int pivot = l;
            while(l!=r){
                while((l<r) && (n[r] > n[pivot])){
                    r--;
                }
                while((l<r) && (n[l] <= n[pivot])){
                    l++;
                    
                }
                if((l!=r) && (n[r] <= n[pivot] || n[l] > n[pivot])){
                    int tmp;
                    tmp = n[r];
                    n[r] = n[l];
                    n[l] = tmp;
                }
            }
            int tmp1;
            tmp1 = n[pivot];
            n[pivot] = n[l];
            n[l] = tmp1;
            return l;
        }
}

现在基本上提示了使用什么算法思路,就可以独立完成刷题了,争取下一步能够不需要提示,自己想出用什么算法思路。刷题很痛苦,但同时也要珍惜这段全力补牢算法基础的时间啊,明天持续更新。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿达斯加

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

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

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

打赏作者

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

抵扣说明:

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

余额充值