2020-10-30每天一刷

力扣33 搜索旋转排序数组

给你一个升序排列的整数数组 nums ,和一个整数 target 。

假设按照升序排序的数组在预先未知的某个点上进行了旋转。(例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。

请你在数组中搜索 target ,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。

示例 1:

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

示例 2:

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

示例 3:

输入:nums = [1], target = 0
输出:-1

提示:

1 <= nums.length <= 5000
-10^4 <= nums[i] <= 10^4
nums 中的每个值都 独一无二
nums 肯定会在某个点上旋转
-10^4 <= target <= 10^4

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:target == nums[mid] 就返回mid;通过nums[begin]和nums[mid]来区分那一部分是有序的,那一部分不是有序的,从而缩小搜素的范围。

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n = nums.size();
        if(!n){
            return -1;
        }
        if(n == 1){
            return target == nums[0] ? 0 : -1;
        }
        int begin =0;
        int end = nums.size()-1;
        while(begin <= end){//这里取等号是因为闭区间
            int mid = begin + (end - begin) / 2;
            if(target == nums[mid]){
                return mid;
            }
            if(nums[begin] <= nums[mid]){//[3,1] target = 1时
                if(target >= nums[begin] && target < nums[mid]){//边界值,要取等号
                    end = mid - 1;
                }
                else
                    begin = mid + 1;
            }
            else{
                if(target > nums[mid] && target <= nums[end]){//注意边界值要取等号
                    begin = mid + 1;
                }
                else{
                    end = mid -1;
                }
            }
        }
        return -1;
    }
};

二叉排序树

  1. 左子树不为空,怎左子树上的所有节点的值均小于或者等于它的根节点的值;
  2. 若右子树不为空,则右子树上所有节点的值均大于或者等于它的根节点的值;
  3. 左右子树也分别为二叉排序树。
  4. 等于的情况只能出现在左子树或者右子树中的某一侧。
    二叉查找树的中序遍历是从小到大的,故又名二叉排序树。

二叉排序树的建立

#include "util.h"
using namespace std;
struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int  x):val(x),left(nullptr),right(nullptr){}
};
//在一个BST树中插入一个新的节点
void BST_insert(TreeNode* node,TreeNode* insert_node){
    if (insert_node->val < node->val){
        if (node->left){
            BST_insert(node->left,insert_node);
        }
        else{
            node->left = insert_node;
        }
    }
    else{
        if (node->right){
            BST_insert(node->right,insert_node);
        }
        else{
            node->right = insert_node;
        }
    }
}
//前序打印BST树
void preorder_print(TreeNode* node, int layer){
    if(!node){
        return;
    }
    for (int i = 0; i < layer; ++i) {
        printf("-----");
    }
    printf("%d\n",node->val);
    preorder_print(node->left,layer+1);
    preorder_print(node->right,layer+1);
}
//查找某一节点是否在BST二叉树中
bool BST_search(TreeNode* node, int value){
    if(node->val == value){
        return true;
    }
    if(value < node->val){
        if(node->left){
            BST_search(node->left,value);
        }
        return false;
    }
    else{
        if (node->right){
            BST_search(node->right,value);
        }
        else{
            return false;
        }
    }
}
int main(){
    //建一个根节点为8的树
    TreeNode root(8);
    vector<TreeNode*> node_vec;
    int test[]= {3,10,1,6,15};
    for (int i = 0; i < 5; ++i) {
        node_vec.push_back(new TreeNode(test[i]));
    }
    for (int i = 0; i < node_vec.size(); ++i) {
        BST_insert(&root,node_vec[i]);
    }
    preorder_print(&root, 0);
    return 0;
}

力扣449 序列化和反序列化二叉搜索树

序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。

设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。

编码的字符串应尽可能紧凑。

示例 1:

输入:root = [2,1,3]
输出:[2,1,3]

示例 2:

输入:root = []
输出:[]

提示:

树中节点数范围是 [0, 104]
0 <= Node.val <= 104
题目数据 保证 输入的树是一棵二叉搜索树。

注意:不要使用类成员/全局/静态变量来存储状态。 你的序列化和反序列化算法应该是无状态的。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/serialize-and-deserialize-bst
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
private:
    void change_int_to_string(int val, string& str_val){
        string tmp;
        while(val){
            tmp += val % 10 + '0';
            val = val / 10;
        }
        for(int i = tmp.length()-1;i >= 0;--i){
            str_val += tmp[i];
        }
        str_val += '#';
    }
    void BST_preorder(TreeNode* node, string& data){
        if(!node){
            return;
        }
        string str_val;
        change_int_to_string(node->val,str_val);
        data += str_val;
        BST_preorder(node->left, data);
        BST_preorder(node->right, data);

        
    }
    void BST_insert(TreeNode* node,TreeNode* insert_node){
    if (insert_node->val < node->val){
        if (node->left){
            BST_insert(node->left,insert_node);
        }
        else{
            node->left = insert_node;
        }
    }
    else{
        if (node->right){
            BST_insert(node->right,insert_node);
        }
        else{
            node->right = insert_node;
        }
    }
} 

public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string data;
        BST_preorder(root, data);
        return data;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if(data.length() == 0){
            return nullptr;
        }
        vector<TreeNode*> node_vec;
        int val = 0;
        for(int i = 0;i<data.length();++i){
            if(data[i] == '#'){
                node_vec.push_back(new TreeNode(val));
                val = 0;
            }
            else{
                val = val * 10 + data[i] - '0';
            }
        }
        for(int i = 1; i < node_vec.size();++i){
            BST_insert(node_vec[0],node_vec[i]);
        }
        return node_vec[0];
    }
};

// Your Codec object will be instantiated and called as such:
// Codec* ser = new Codec();
// Codec* deser = new Codec();
// string tree = ser->serialize(root);
// TreeNode* ans = deser->deserialize(tree);
// return ans;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值