文章目录
1.预备知识
1.1 题目目录
1.2 二分查找
1.3 递归二分查找
bool binary_search(vector<int>& sort_array, int begin, int end, int target) {
if (begin>end) {
return false;
}
int mid = (begin + end) / 2;
if (target == sort_array[mid]) {
return true;
}
else if (target < sort_array[mid]) {
binary_search(sort_array, begin, mid - 1, target);
}
else if (target > sort_array[mid]) {
binary_search(sort_array, mid + 1, end, target);
}
}
1.4 循环二分查找
bool binary_search(vector<int>& sort_array, int target) {
int begin = 0;
int end = sort_array.size() - 1;
while (begin<=end) {
int mid = (begin + end) / 2;
if (target == sort_array[mid]) {
return true;
}
else if(target < sort_array[mid]) {
end = mid - 1;
}
else if (target > sort_array[mid]) {
begin = mid + 1;
}
}
return false;
}
1.5 二叉查找(排序)树
1.6 二叉搜索树的代码实现
1.二叉搜索树的插入
void solution::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;
}
}
}
2.二叉搜索树的搜索
bool solution::BST_search(TreeNode* node, int value) {
if (value == node->val) {
return true;
}
else if (value < node->val) {
if (node->left) {
BST_search(node->left, value);
}
else {
return false;
}
}
else if (value > node->val) {
if (node->right) {
BST_search(node->right, value);
}
else {
return false;
}
}
}
2.搜索插入位置
2.1 题目描述
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
2.2 C++代码实现
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int begin=0;
int end=nums.size()-1;
int index=-1;
while(index==-1){
int mid=(begin+end)/2;
if(target==nums[mid]){
index=mid;
}
else if(target<nums[mid]){
if(mid==0||target>nums[mid-1]){
index=mid;
}
end=mid-1;
}
else if(target>nums[mid]){
if(mid==nums.size()-1||target<nums[mid+1]){
index= mid+1;
}
begin=mid+1;
}
}
return index;
}
};
3.区间查找
3.1 题目描述
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
3.2 算法思路
3.3 C++代码实现
class Solution {
public:
int left_bound(vector<int>& nums,int target){
int begin=0;
int end=nums.size()-1;
while(begin<=end){
int mid=(begin+end)/2;
if(target==nums[mid]){
if(mid==0||target>nums[mid-1]){
return mid;
}
end=mid-1;
}
else if(target<nums[mid]){
end=mid-1;
}
else if(target>nums[mid]){
begin=mid+1;
}
}
return -1;
}
int right_bound(vector<int>& nums,int target){
int begin=0;
int end=nums.size()-1;
while(begin<=end){
int mid=(begin+end)/2;
if(target==nums[mid]){
if(mid==nums.size()-1||target<nums[mid+1]){
return mid;
}
begin=mid+1;
}
else if(target<nums[mid]){
end=mid-1;
}
else if(target>nums[mid]){
begin=mid+1;
}
}
return -1;
}
vector<int> searchRange(vector<int>& nums, int target) {
int left=left_bound(nums,target);
int right=right_bound(nums,target);
vector<int> result;
result.push_back(left);
result.push_back(right);
return result;
}
};
4.旋转数组查找
4.1 题目描述
整数数组 nums 按升序排列,数组中的值 互不相同 。
在传递给函数之前,nums 在预先未知的某个下标 k(0 <= k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k+1], …, nums[n-1], nums[0], nums[1], …, nums[k-1]](下标 从 0 开始 计数)。例如, [0,1,2,4,5,6,7] 在下标 3 处经旋转后可能变为 [4,5,6,7,0,1,2] 。
给你 旋转后 的数组 nums 和一个整数 target ,如果 nums 中存在这个目标值 target ,则返回它的下标,否则返回 -1 。
4.2 解题思路
4.3 C++代码实现
class Solution {
public:
int search(vector<int>& nums, int target) {
int begin=0;
int end=nums.size()-1;
while(begin<=end){
int mid=(begin+end)/2;
if(target==nums[mid]){
return mid;
}
else if(target<nums[mid]){
if(nums[begin]<nums[mid]){
if(target>=nums[begin]){
end=mid-1;
}
else{
begin=mid+1;
}
}
else if(nums[begin]>nums[mid]){
end=mid-1;
}
else if(nums[begin]==nums[mid]){
begin=mid+1;
}
}
else if(target>nums[mid]){
if(nums[begin]<nums[mid]){
begin=mid+1;
}
else if(nums[begin]>nums[mid]){
if(target>=nums[begin]){
end=mid-1;
}
else{
begin=mid+1;
}
}
else if(nums[begin]==nums[mid]){
begin=mid+1;
}
}
}
return -1;
}
};
5.序列化和反序列化二叉搜索树
5.1 题目描述
序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。
设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。
编码的字符串应尽可能紧凑。
5.2 算法思路
5.3 C++代码实现
class Codec {
public:
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;
}
}
}
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 += '#';
}
/*9.2 将二叉查找树按照前序遍历的方式,转化为字符串,数字之间使用#隔开*/
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);
}
// 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) {
int val=0;
vector<TreeNode*> node_vec;
if(data.length()==0){
return NULL;
}
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];
}
};
6.计算右侧小于当前元素的个数
6.1 题目描述
给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。
示例:
输入:nums = [5,2,6,1]
输出:[2,1,1,0]
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素
6.2 算法思路
6.3 C++代码实现
struct BSTNode{
int val;
int count;
BSTNode* left;
BSTNode* right;
BSTNode(int x):val(x),count(0),left(NULL),right(NULL){}
};
class Solution {
public:
void BSTInsert(BSTNode* node,BSTNode* insert_node,int& count_small){
if(insert_node->val<=node->val){
node->count++;
if(node->left){
BSTInsert(node->left,insert_node,count_small);
}
else{
node->left=insert_node;
}
}
else{
count_small+=node->count+1;
if(node->right){
BSTInsert(node->right,insert_node,count_small);
}
else{
node->right=insert_node;
}
}
}
vector<int> countSmaller(vector<int>& nums) {
vector<int> result;
vector<int> count;
vector<BSTNode*> node_vec;
for(int i=nums.size()-1;i>=0;i--){
node_vec.push_back(new BSTNode(nums[i]));
}
count.push_back(0);
for(int i=1;i<node_vec.size();i++){
int count_small=0;
BSTInsert(node_vec[0],node_vec[i],count_small);
count.push_back(count_small);
}
for(int i=node_vec.size()-1;i>=0;i--){
delete node_vec[i];
result.push_back(count[i]);
}
return result;
}
};