117:Search for a Range

题目:Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm’s runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1].
For example, Given [5, 7, 7, 8, 8, 10] and target value 8, return [3, 4].

解析1:我们可以使用 c++ STL 提供的 lower_bound 和 upper_bound 函数来求解这个问题。

代码如下:

// 使用 STL 中提供的 lower_bound 和 upper_bound 函数
// upper_bound 返回一个迭代器,指向[first, last) 中第一个大于 target 的元素
// lower_bound 返回一个迭代器,指向[first, last) 中打一个大于等于 target 的元素
// 因此如果 tagret 在 [first, last) 范围内不存在
// 则 lower_bound 与 upper_bound 应返回相同的迭代器
// 时间复杂度为 O(logn)
class Solution {
public:
        vector<int> searchRange(vector<int>& nums, int target) {
                auto lower = lower_bound(nums.begin(), nums.end(), target);
                auto upper = upper_bound(lower, nums.end(), target);

                // target 在数组 nums 中不存在
                if (lower == upper) return vector<int>{-1, -1};

                // target 在数组 nums 中存在
                const int l = distance(nums.begin(), lower);
                const int u = distance(nums.begin(), prev(upper));
                return vector<int>{l, u};
        }
};

解析2:我们可以自己写代码实现 lower_bound 和 upper_bound 函数,代码如下:

// 不借助于 STL,自己实现 lower_bound 和 upper_bound
// 时间复杂度 O(logn),空间复杂度 O(1)
class Solution {
public:
        vector<int> searchRange(vector<int>& nums, int target) {
                auto lower = lower_bound(nums.begin(), nums.end(), target);
                auto upper = upper_bound(lower, nums.end(), target);

                // target 在数组 nums 中不存在
                if (lower == upper) return vector<int>{-1, -1};

                // target 在数组 nums 中存在
                const int l = distance(nums.begin(), lower);
                const int u = distance(nums.begin(), prev(upper));
                return vector<int>{l, u};
        }
private:
        template<class ForwardIterator, class T>
        ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, T target) {
                while (first != last) {
                        size_t len = last - first;
                        auto mid = next(first, len / 2);
                        if (*mid < target) first = ++mid;
                        else last = mid;
                }
                return first;
        }

        template <class ForwardIterator, class T>
        ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last, T target) {
                while (first != last) {
                        size_t len = last - first;
                        auto mid = next(first, len / 2);
                        if (*mid <= target) first = ++mid;
                        else last = mid;
                }
                return first;
        }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Sure, here's an implementation of a hash table with chaining in Python: ```python import random class HashTable: def __init__(self, capacity=10): self.capacity = capacity self.size = 0 self.table = [[] for _ in range(self.capacity)] def hash(self, key): hash_value = 0 for i in range(len(key)): hash_value = (hash_value * 31 + ord(key[i])) % self.capacity return hash_value def search(self, key): hash_value = self.hash(key) bucket = self.table[hash_value] for i in range(len(bucket)): if bucket[i][0] == key: return True return False def insert(self, key): if self.search(key): return hash_value = self.hash(key) bucket = self.table[hash_value] bucket.append((key, None)) self.size += 1 if self.size >= self.capacity * 0.7: self._resize() def delete(self, key): hash_value = self.hash(key) bucket = self.table[hash_value] for i in range(len(bucket)): if bucket[i][0] == key: bucket.pop(i) self.size -= 1 if self.size <= self.capacity * 0.3: self._resize() return def size(self): return self.capacity def _resize(self): self.capacity *= 2 new_table = [[] for _ in range(self.capacity)] for bucket in self.table: for key, value in bucket: hash_value = self.hash(key) new_table[hash_value].append((key, value)) self.table = new_table ``` The `__init__` method initializes the hash table with a specified capacity (default is 10), and creates a list of empty lists to represent the buckets. The `hash` method takes in a key and maps it to an integer value between 0 and the capacity of the table using a hash function. In this case, we're using a simple polynomial rolling hash function. The `search` method searches for a key in the table by computing its hash value and checking if it exists in the corresponding bucket. The `insert` method inserts a key into the table by computing its hash value and appending it to the corresponding bucket. If the load factor of the table exceeds 0.7, the table is resized to double its capacity. The `delete` method deletes a key from the table by computing its hash value and removing it from the corresponding bucket. If the load factor of the table falls below 0.3, the table is resized to half its capacity. The `size` method simply returns the current capacity of the table. The `_resize` method is a private helper method that is called by the `insert` and `delete` methods when the load factor threshold is exceeded. It creates a new table with double or half the capacity of the current table, and rehashes all the keys in the old table into the new table.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值