二叉搜索树中第K小的元素

问题描述

给定一个二叉搜索树,编写一个函数 kthSmallest 来查找其中第 k 个最小的元素。
说明:
你可以假设 k 总是有效的,1 ≤ k ≤ 二叉搜索树元素个数。

示例 1:

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

示例 2:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-smallest-element-in-a-bst

思路

二叉搜索树的性质是,根节点的左边比其小,右边比其大。
本题的思路是将搜索二叉树存到一个vector ret中,ret升序排列的。
题目要求第k小的元素,所以ret[k-1]即为最终结果。

题解

class Solution {
public:
    vector<int> ret;
    int kthSmallest(TreeNode* root, int k) {
        dfs(root);
        return ret[k-1];
    }
    void dfs(TreeNode *node){
        if(node== nullptr) return;
        dfs(node->left);
        ret.push_back(node->val);
        dfs(node->right);
    }
};

数组中的第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 ≤ 数组的长度。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array

思路

用了排序,从大到小进行了排序
注意:在类中的函数要加static才能在生成对象前在类中调用

题解

class Solution {
public:
    static bool cmp(int left, int right) {
        return left > right;
    }

    int findKthLargest(vector<int> &nums, int k) {
        int n = nums.size();
        sort(nums.begin(), nums.end(), cmp);
        
        return nums[k - 1];

    }
};

在排序数组中查找元素的第一个和最后一个位置

问题描述

给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。

示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]

示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array

思路

emmmm,复杂度为O(n)

题解

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        int n=nums.size();
        vector<int> ret;
        int min=-1;
        int max=-1;
        for(int i=0;i<n;i++){
            if(target==nums[i]){
                min=i;
                break;
            }
        }
        for(int i=0;i<n;i++){
            if(target==nums[i]){
                max=i;
            }
        }
        ret.push_back(min);
        ret.push_back(max);
        return ret;
    }
};

全排列

问题描述

给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:
输入: [1,2,3]
输出:
[
[1,2,3],
[1,3,2],
[2,1,3],
[2,3,1],
[3,1,2],
[3,2,1]
]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/permutations

思路

回溯算法,和以前的做法一样,详情见以前的题目。

题解

class Solution {
public:
    bool visited[100] = {false};
    vector<int> B;
    vector<vector<int> > A;

    vector<vector<int>> permute(vector<int> &nums) {
        dfs(nums,A,0);
        return A;
    }
    void dfs(vector<int> &nums, vector<vector<int>> &A, int step) {
        int n = nums.size();
        if (step == n) {
            A.push_back(B);
            return;
        }
        for (int i = 0; i <n;i++)
        {
            if(visited[i]==false)
            {
                visited[i]=true;
                B.push_back(nums[i]);
                dfs(nums,A,step+1);
                visited[i]= false;
                B.pop_back();
            }
        }
    }
};

搜索旋转排序数组

问题描述

假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。

示例 1:
输入: nums = [4,5,6,7,0,1,2], target = 0
输出: 4

示例 2:
输入: nums = [4,5,6,7,0,1,2], target = 3
输出: -1

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array

思路

题目中要求算法时间复杂度必须是 O(log n) 级别->用二分查找。
题目中给出数组在某个点进行了旋转,数组在旋转之前是升序排列的,因此,最小的点即为旋转点。
找到了旋转点之后,将数组至多分为两个二分查找。
在两部分分别进行二分查找后,没找到目标值返回-1,如果找到返回坐标i,i一定大于-1.因此在两部分二分查找的结果中找最大值即可。

题解

class Solution {
public:
    int search(vector<int> &nums, int target) {
        int n = nums.size();
        if(n==0){
            return -1;
        }
        int min = nums[0];
        int flag = 0;
        for (int i = 1; i < n; i++) {
            if (min > nums[i]) {
                min = nums[i];
                flag = i;
            }
        }

        int location1 = refen(-1, nums, 0, flag - 1, target);
        int location2 = refen(-1, nums, flag, n - 1, target);
        return max(location1,location2);
    }

    int refen(int location, vector<int> &nums, int first, int last, int target) {
        int mid;
        while (first <= last && first >= 0 && last <= nums.size()) {
            mid = (first + last) / 2;
            if (target > nums[mid]) {
                first = mid + 1;
            } else if (target < nums[mid]) {
                last = mid - 1;
            } else {
                location = mid;
                break;
            }
        }
        return location;
    }
};