2024-03-08 leetcode写题记录

2024-03-08 leetcode写题记录

27. 移除元素

题目链接

27. 移除元素

题意

给你一个数组\(nums\)和一个值\(val\),你需要原地移除所有数值等于\(val\)的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用\(O(1)\)额外空间并原地修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素

解法

遍历一遍,把不等于\(val\)的值都\(swap\)到前面即可。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int n = nums.size(), idx = 0;
        for (int i = 0; i < n; ++i) {
            if (nums[i] == val)
                continue;
            swap(nums[idx], nums[i]);
            idx++;
        }
        return idx;
    }
};

179. 最大数

题目链接

170. 最大数

题意

给定一组非负整数\(nums\),重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。

注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。

解法

用贪心的想法想一下,两个数的比较其实就是在比哪个数在前时能让整个数变得更大。

注意,\(f()\)会爆\(int\)

class Solution {
   public:
    int f(int x) {
        long long res = 10;
        while(x >= res) res *= 10;
        return res;
    }

    string largestNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end(), [&](int& x, int& y) {
            int xx = f(x), yy = f(y);
            return 1ll * x * yy + y > 1ll * y * xx + x;
        });
        if (nums[0] == 0) return "0";
        string res = "";
        for (int x : nums)
            res += to_string(x);
        return res;
    }
};

75. 颜色分类

题目链接

75. 颜色分类

题意

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

我们使用整数\(0、1\)\(2\)分别表示红色、白色和蓝色。

必须在不使用库内置的\(sort\)函数的情况下解决这个问题。

解法

遍历一遍,是\(0\)就扔左边,是\(2\)就扔右边,处理好边界就行了。

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n = nums.size(), l = 0, r = n - 1;
        for (int i = l; i <= r; ++i) {
            if (nums[i] == 0) 
                swap(nums[l++], nums[i--]);
            else if (nums[i] == 2) 
                swap(nums[r--], nums[i--]);
            if (i < l - 1) i = l - 1;
        }
    }
};

215. 数组中的第K个最大元素

先吐槽,这题真垃圾。题目上写着让想时间复杂度\(O(n)\)的算法,但是官方题解说的什么玩意都是,时间复杂度还不写最坏时间复杂度,测试数据又卡的离谱,怪不得讨论区一堆骂的,给我卡麻了。这题想\(O(nlogn)\)的就行。

题目链接

215. 数组中的第K个最大元素

题意

给定整数数组\(nums\)和整数\(k\),请返回数组中第\(k\)个最大的元素。

请注意,你需要找的是数组排序后的第\(k\)个最大的元素,而不是第\(k\)个不同的元素。

解法

快速排序

快排的\(partition\)不稳定,这个题也没能过完所有样例,所以一般也不用。这里之所以写是为了回顾下快排写法,防止面试卡住。

image

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int n = nums.size(), l = 0, r = n - 1, now = -1, des = n - k;
        while (now != des) {
            if (now < des)
                now = partition(nums, now + 1, r);
            else
                now = partition(nums, l, now - 1);
        }
        return nums[now];
    }

    int partition(vector<int>& a, int begin, int end) {
        int l = begin, r = end;
        while (l < r) {
            while (l < end && a[l] <= a[begin])
                l++;
            while (begin < r && a[r] >= a[begin])
                r--;
            if (l < r)
                swap(a[l], a[r]);
        }
        swap(a[begin], a[r]);
        return r;
    }
};

二分

正负数都有的二分,注意边界判断。

class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int l = -10005, r = 10005;
        while(l < r) {
            int mid = (l + r) / 2 + 1, sum = 0;
            if (l + r < 0) mid--;
            for (int x : nums)
                if (x >= mid) sum += 1;
            if (sum < k)
                r = mid - 1;
            else
                l = mid;
        }
        return l;
    }
};

大根堆

手敲下大根堆。

写堆只要注意写好\(heapify()\)就行,其他的操作都是由这转化过去的。

class Solution {
   public:
    void heapify(vector<int>& a, int idx) {
        if (idx < 0) return;
        int n = a.size();
        if (idx >= n) return;
        int l = 2 * idx + 1, r = 2 * idx + 2;
        if (l >= n) return;
        if (r == n) {
            if (a[idx] < a[l]) swap(a[idx], a[l]);
            return;
        }
        if (a[idx] >= a[l] && a[idx] >= a[r]) return;
        int next_idx = (a[l] > a[idx] && a[l] >= a[r]) ? l : r;
        swap(a[idx], a[next_idx]);
        heapify(a, next_idx);
    }

    void build(vector<int>& a) {
        int n = a.size();
        for (int i = n / 2 - 1; i >= 0; --i) heapify(a, i);
    }

    void del(vector<int>& a) {
        a[0] = -100000;
        heapify(a, 0);
    }

    int findKthLargest(vector<int>& nums, int k) {
        build(nums);
        for (int i = 0; i < k - 1; ++i) del(nums);
        return nums[0];
    }
};
posted @ 2024-03-08 17:55  FlyingLight  阅读(9)  评论(0编辑  收藏  举报