Day-06-二分搜索和二叉排序树 Leetcode-35, 34, 33, 449, 315

我与影子孤独终老i 提交于 2019-11-29 15:12:02


#include <stdio.h>
#include <vector>
// //二分查找(递归)
// bool binary_search(std::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]){
//            return binary_search(sort_array, begin, mid-1, target);
//     }
//     else if(target > sort_array[mid]){
//            return binary_search(sort_array, mid+1, end, target);
//     }
// }
//二分查找(循环)
bool binary_search(std::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;
}

例一:LeetCode35

//给定一个排序数组nums(无重复元素)与目标值target
//如果target在nums中出现,则返回target所在下标,如果target
//在nums中未出现,则返回插入位置下标,使得将target插入nums
//后nums数组任然有序
#include <stdio.h>
#include <vector>
class Solution {
public:
       int searchInsert(std::vector<int>& nums, int target) {
              int index = -1;
              int begin = 0;
              int end = nums.size() - 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;
       }
};
int main() {
       int test[] = { 1, 3, 4, 6 };
       std::vector<int> nums;
       Solution solve;
       for (int i = 0; i < 8; i++) {
              nums.push_back(test[i]);
       }
       for (int i = 0; i < 8; i++) {
              printf("i = %d index = %d\n", i, solve.searchInsert(nums, i));
       }
       return 0;
}

例二:LeetCode34




//给定一个排序数组nums(有重复元素)与目标值target
//如果target在nums中出现,则返回target所在区间的左右端点
//下标,如果target在nums中未出现,则返回[-1,-1]
#include <stdio.h>
#include <vector>
class Solution {
public:
       std::vector<int> searchRange(std::vector<int>& nums, int target) {
              std::vector<int> result;
              result.push_back(left_bound(nums, target));
              result.push_back(right_bound(nums, target));
              return result;
       }
private:
       int left_bound(std::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 || nums[mid - 1] < target) {
                                  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(std::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 || nums[mid + 1] > target) {
                                  return mid;
                           }
                           begin = mid + 1;
                     }
                     else if (target < nums[mid]) {
                           end = mid - 1;
                     }
                     else if (target > nums[mid]) {
                           begin = mid + 1;
                     }
              }
              return -1;
       }
};
int main() {
       int test[] = { 5, 7, 7, 8, 8, 8, 8, 10 };
       std::vector<int> nums;
       Solution solve;
       for (int i = 0; i < 8; i++) {
              nums.push_back(test[i]);
       }
       for (int i = 0; i < 12; i++) {
              std::vector<int> result = solve.searchRange(nums, i);
              printf("%d : [%d, %d]\n", i, result[0], result[1]);
       }
       return 0;
}

例三:LeetCode33



/**Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
You are given a target value to search. If found in the array return its index, otherwise return -1.
You may assume no duplicate exists in the array.
Your algorithm's runtime complexity must be in the order of O(log n).
给定要给排序数组nums(nums中无重复元素),且nums可能以
某个未知下标旋转,给定目标值target,求target是否在nums中出现
若出现返回所在下标,未出现返回-1
*/
#include <vector>
#include <stdio.h>
class Solution {
public:
       int search(std::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;
       }
};
int main() {
       int test[] = { 9, 12, 15, 20, 1 , 3, 6, 7 };
       std::vector<int> nums;
       Solution solve;
       for (int i = 0; i < 8; i++) {
              nums.push_back(test[i]);
       }
       for (int i = 0; i < 22; i++) {
              printf("%d : %d\n", i, solve.search(nums, i));
       }
       return 0;
}

例四:LeetCode449



//二叉排序树,插入新节点
#include <stdio.h>
#include <vector>
struct TreeNode {
       int val;
       TreeNode* left;
       TreeNode* right;
       TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
void BFS_insert(TreeNode* node, TreeNode* insert_node) {
       if (insert_node->val < node->val) {
              if (node->left) {
                     BFS_insert(node->left, insert_node);
              }
              else {
                     node->left = insert_node;
              }
       }
       else {
              if (node->right) {
                     BFS_insert(node->right, insert_node);
              }
              else {
                     node->right = insert_node;
              }
       }
}
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);
}
int main() {
       TreeNode root(8);
       std::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++) {
              BFS_insert(&root, node_vec[i]);
       }
       preorder_print(&root, 0);
       for (int i = 0; i < node_vec.size(); i++) {
              delete(node_vec[i]);
       }
       return 0;
}

//二叉查找树查找数值
#include <stdio.h>
#include <vector>
struct TreeNode {
       int val;
       TreeNode* left;
       TreeNode* right;
       TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
bool BSF_search(TreeNode* node, int value) {
       if (node->val == value) {
              return true;
       }
       if (node->val > value) {
              if (node->left) {
                     return BSF_search(node->left, value);
              }
              else
                     return false;
       }
       else {
              if (node->right) {
                     return BSF_search(node->right, value);
              }
              else {
                     return false;
              }
       }
}
int main() {
       TreeNode a(8);
       TreeNode b(3);
       TreeNode c(10);
       TreeNode d(1);
       TreeNode e(6);
       TreeNode f(15);
       a.left = &b;
       a.right = &c;
       b.left = &d;
       b.right = &e;
       c.right = &f;
       for (int i = 0; i < 20; i++) {
              if (BSF_search(&a, i)) {
                     printf("%d is in the BFS.\n", i);
              }
              else {
                     printf("%d is not in the BFS.\n", i);
              }
       }
       return 0;
} 

//二叉排序树,插入新节点
#include <stdio.h>
#include <vector>
#include <string>
struct TreeNode {
       int val;
       TreeNode* left;
       TreeNode* right;
       TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
//对二叉查找树进行前序遍历, 将遍历得到的节点存储到node_vec中
void collect_nodes(TreeNode* node, std::vector<TreeNode*>& node_vec) {
       if (!node) {
              return;
       }
       node_vec.push_back(node);
       collect_nodes(node->left, node_vec);
       collect_nodes(node->right, node_vec);
}
void BFS_insert(TreeNode* node, TreeNode* insert_node) {
       if (insert_node->val < node->val) {
              if (node->left) {
                     BFS_insert(node->left, insert_node);
              }
              else {
                     node->left = insert_node;
              }
       }
       else {
              if (node->right) {
                     BFS_insert(node->right, insert_node);
              }
              else {
                     node->right = insert_node;
              }
       }
}
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);
}
int main() {
       TreeNode a(8);
       TreeNode b(3);
       TreeNode c(10);
       TreeNode d(1);
       TreeNode e(6);
       TreeNode f(15);
       a.left = &b;
       a.right = &c;
       b.left = &d;
       b.right = &e;
       c.right = &f;
       std::vector<TreeNode*> node_vec;
       collect_nodes(&a, node_vec);
       for (int i = 0; i < node_vec.size(); i++) {
              node_vec[i]->left = NULL;
              node_vec[i]->right = NULL;
       }
       for (int i = 1; i < node_vec.size(); i++) {
              BFS_insert(node_vec[0], node_vec[i]);
       }
       preorder_print(node_vec[0], 0);
       return 0;
}



/** Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer,
or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on
how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be
serialized to a string and this string can be deserialized to the original tree structure.
The encoded string should be as compact as possible.
Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.
给定一个二叉查找树,实现对该二叉查找树编码与解码功能。
编码即将该二叉查找树转为字符串,解码即将字符串转化为二叉查找树。
不限制使用何种编码算法,只要保证当对二叉树调用编码功能后可再调
用解码功能将其复原。
 */
#include <stdio.h>
#include <vector>
#include <string>
struct TreeNode {
       int val;
       TreeNode* left;
       TreeNode* right;
       TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Codec {
public:
       std::string serialize(TreeNode* root) {
              std::string data;
              BFS_preorder(root, data);
              return data;
       }
       TreeNode* deserialize(std::string data) {
              if (data.length() == 0) {
                     return NULL;
              }
              std::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++) {
                     BFS_insert(node_vec[0], node_vec[i]);
              }
              return node_vec[0];
       }
private:
       void change_int_to_string(int val, std::string& str_val) {
              std::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 BFS_preorder(TreeNode* node, std::string& data) {
              if (!node) {
                     return;
              }
              std::string str_val;
              change_int_to_string(node->val, str_val);
              data += str_val;
              BFS_preorder(node->left, data);
              BFS_preorder(node->right, data);
       }
       void BFS_insert(TreeNode* node, TreeNode* insert_node) {
              if (insert_node->val < node->val) {
                     if (node->left) {
                           BFS_insert(node->left, insert_node);
                     }
                     else {
                           node->left = insert_node;
                     }
              }
              else {
                     if (node->right) {
                           BFS_insert(node->right, insert_node);
                     }
                     else {
                           node->right = insert_node;
                     }
              }
       }
};
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);
}
int main() {
       TreeNode a(8);
       TreeNode b(3);
       TreeNode c(10);
       TreeNode d(1);
       TreeNode e(6);
       TreeNode f(15);
       a.left = &b;
       a.right = &c;
       b.left = &d;
       b.right = &e;
       c.left = &f;
       Codec solve;
       std::string data = solve.serialize(&a);
       printf("%s\n", data.c_str());
       TreeNode* root = solve.deserialize(data);
       preorder_print(root, 0);
       return 0;
}

例五:LeetCode315




#include <stdio.h>
#include <vector>
//记录左子树数量的而查查找树
struct BSTNode {
       int val;
       int count;
       BSTNode* left;
       BSTNode* right;
       BSTNode(int x) : val(x), left(NULL), right(NULL), count(0) {}
};
class Solution {
public:
       std::vector<int> countSmaller(std::vector<int>& nums) {
              std::vector<int> result;
              std::vector<BSTNode*> node_vec;
              std::vector<int> count;
              for (int i = nums.size() - 1; i >= 0; i--) {
                     node_vec.push_back(new BSTNode(nums[i]));//new 返回的是新 BSTNode 的地址
              }
              count.push_back(0);
              for (int i = 1; i < node_vec.size(); i++) {
                     int count_small = 0;
                     BST_insert(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;
       }
private:
       void BST_insert(BSTNode* node, BSTNode* insert_node, int& count_small) {
              if (insert_node->val <= node->val) {
                     node->count++;
                     if (node->left) {
                           BST_insert(node->left, insert_node, count_small);
                     }
                     else {
                           node->left = insert_node;
                     }
              }
              else {
                     count_small += node->count + 1;
                     if (node->right) {
                           BST_insert(node->right, insert_node, count_small);
                     }
                     else {
                           node->right = insert_node;
                     }
              }
       }
};
int main() {
       int test[] = { 5, -7, 9, 1, 3, 5, -2, 1 };
       std::vector<int> nums;
       for (int i = 0; i < 8; i++) {
              nums.push_back(test[i]);
       }
       Solution solve;
       std::vector<int> result = solve.countSmaller(nums);
       for (int i = 0; i < result.size(); i++) {
              printf("[%d]", result[i]);
       }
       printf("\n");
       return 0;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!