• 面试_第K问题


    215. 数组中的第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 <= 104
    -104 <= nums[i] <= 104
    
    class Solution:
    
        def findKthLargest(self, nums: List[int], k: int) -> int:
            # start, end = 0, len(nums)
            # if end == 1:
            #     return nums[0]
            # if k > end:
            #     return -1
           
            # def partition(low, high):
            #     m = randint(low, high)
            #     nums[low], nums[m] = nums[m], nums[low]
            #     qivot = nums[low]
            #     # 降序
            #     while low < high:
            #         while low < high and nums[high] <= qivot: high -= 1
            #         nums[low] = nums[high]
            #         while low < high and nums[low] >= qivot: low += 1
            #         nums[high] = nums[low]
            #     nums[low] = qivot
            #     return low
    
            # def qsort(low, high):
            #     pivotloc = partition(low, high)
            #     if pivotloc >  k - 1:
            #         return qsort(low, pivotloc - 1)
            #     elif pivotloc < k - 1:
            #         return qsort(pivotloc + 1, high)
            #     return nums[k - 1]
    
            # return qsort(start, end - 1)
    
            start, end = 0, len(nums)
            if k > end:
                return -1
           
            def partition(low, high):
                m = randint(low, high)
                nums[low], nums[m] = nums[m], nums[low]
                qivot = nums[low]
                # 升序
                while low < high:
                    while low < high and nums[high] >= qivot: high -= 1
                    nums[low] = nums[high]
                    while low < high and nums[low] <= qivot: low += 1
                    nums[high] = nums[low]
                nums[low] = qivot
                return low
    
            def qsort(low, high):
                pivotloc = partition(low, high)
                # 因为是升序,第k大数是,n - k
                if pivotloc >  end - k:
                    return qsort(low, pivotloc - 1)
                elif pivotloc < end - k:
                    return qsort(pivotloc + 1, high)
                return nums[end - k]
    
            return qsort(start, end - 1)
    

    时间复杂度:O(n);空间复杂度:O(logn)
    法二:大顶堆

    class Solution {
    public:
        void maxHeapify(vector<int>& a, int i, int heapSize) {
            int l = i * 2 + 1, r = i * 2 + 2, largest = i;
            if (l < heapSize && a[l] > a[largest]) {
                largest = l;
            } 
            if (r < heapSize && a[r] > a[largest]) {
                largest = r;
            }
            if (largest != i) {
                swap(a[i], a[largest]);
                maxHeapify(a, largest, heapSize);
            }
        }
    
        void buildMaxHeap(vector<int>& a, int heapSize) {
            for (int i = heapSize / 2; i >= 0; --i) {
                maxHeapify(a, i, heapSize);
            } 
        }
    
        int findKthLargest(vector<int>& nums, int k) {
            int heapSize = nums.size();
            buildMaxHeap(nums, heapSize);
            for (int i = nums.size() - 1; i >= nums.size() - k + 1; --i) {
                swap(nums[0], nums[i]);
                --heapSize;
                maxHeapify(nums, 0, heapSize);
            }
            return nums[0];
        }
    };
    

    时间复杂度:O(nlogn)
    空间复杂度:O(logn)

    面试题40. 最小的k个数

    输入整数数组 arr ,找出其中最小的 k 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。

    示例 1:

    输入:arr = [3,2,1], k = 2
    输出:[1,2] 或者 [2,1]
    示例 2:

    输入:arr = [0,1,2,1], k = 1
    输出:[0]

    限制:

    0 <= k <= arr.length <= 10000
    0 <= arr[i] <= 10000
    
    class Solution:
        # def selectPartition(self, arr, low, high):
        #     mid = (low + high) // 2
        #     if arr[mid] > arr[high]:
        #         arr[mid], arr[high] = arr[high], arr[mid]
        #     if arr[low] > arr[high]:
        #         arr[low], arr[high] = arr[high], arr[low]
        #     if arr[mid] > arr[low]:
        #         arr[mid], arr[low] = arr[low], arr[mid]
    
        def partition(self, arr, low, high):
            # self.selectPartition(arr, low, high)
            # m = (low + high) // 2
            m = randint(low, high)
            arr[low], arr[m] = arr[m], arr[low]
            pivot = arr[low]
            while low < high:
                while low < high and arr[high] >= pivot: high -=1
                arr[low] = arr[high]
                while low < high and arr[low] <= pivot: low += 1
                arr[high] = arr[low]
            arr[low] = pivot
            return low
        
        def selectTopK(self, arr, low, high, k):
            pivotloc = self.partition(arr, low, high)
            if pivotloc < k - 1:
                return self.selectTopK(arr, pivotloc + 1, high, k)
            elif pivotloc > k - 1:
                return self.selectTopK(arr, low, pivotloc - 1, k)
    
            return arr[:k]
            
        def getLeastNumbers(self, arr, k):
            alen = len(arr)
            if k == 0 or k > alen:
                return []
            if alen == 0:
                return []
            
            return self.selectTopK(arr, 0, alen - 1, k)
    

    时间复杂度:O(n), 空间复杂度:O(logn)

    剑指 Offer 22. 链表中倒数第k个节点

    输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。

    例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

    示例:

    给定一个链表: 1->2->3->4->5, 和 k = 2. 返回链表 4->5.

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode* getKthFromEnd(ListNode* head, int k) {
            if (head == nullptr) {
                return nullptr;
            }
            
            ListNode *slow = head, *fast = head;
            for (int i = 0; i < k && fast; i++)
            {
                fast = fast->next;
            }
            while (slow && fast)
            {
                slow = slow->next; fast = fast->next;
            }
            return slow;
        }
    };
    

    剑指 Offer 54. 二叉搜索树的第k大节点

    给定一棵二叉搜索树,请找出其中第 k 大的节点的值。

    示例 1:

    输入: root = [3,1,4,null,2], k = 1
    3
    /
    1 4

    2
    输出: 4
    示例 2:

    输入: root = [5,3,6,2,4,null,null,1], k = 3
    5
    /
    3 6
    /
    2 4
    /
    1
    输出: 4

    限制:

    1 ≤ k ≤ 二叉搜索树元素个数
    
    /**
     * Definition for a binary tree node.
     * struct TreeNode {
     *     int val;
     *     TreeNode *left;
     *     TreeNode *right;
     *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
     * };
     */
    class Solution {
        int ans;
        int cur;
    public:
        void dfs(TreeNode* root)
        {
            if (root == nullptr) {
                return;
            }
            dfs(root->right);
            if (cur == 0) {
                return;
            }
            cur--;
            if (cur == 0) {
                ans = root->val;
                return;
            }
            dfs(root->left);
        }
        int kthLargest(TreeNode* root, int k) {
            cur = k;
            dfs(root);
    
            return ans;
        }
    };
    

    时间复杂度:O(n)
    空间复杂度:O(n)

  • 相关阅读:
    TF-IDF基本原理简释
    岭回归(Ridge Regression)、OLS和吉洪诺夫正则化(Тихонов regularization)
    论文笔记[8] Seismic Waveform Classification and First-Break Picking Using CNN
    如何科学地使用keras的Tokenizer进行文本预处理
    集成学习(Ensemble)相关概念及算法(Adaboost,Bagging,Stacking)
    论文笔记 [7] complex-trace analysis for temporal resolution improvement
    关于python的一些笔记 2018-03-01 00:04:54
    Keras文本预处理相关函数简介(text preprocessing)
    python中re模块正则表达式(Regular Expression)的基本用法示例
    循环神经网络(RNN)中的LSTM和GRU模型的内部结构与意义
  • 原文地址:https://www.cnblogs.com/douzujun/p/16458669.html
Copyright © 2020-2023  润新知