楼主: 14417335
跳转到指定楼层
上一主题 下一主题
收起左侧

[二分/排序/搜索] 无序数组二分搜索:找不到的数

🔗
mooc 2019-3-31 11:08:41 | 只看该作者
全局:
这道题不难的, 能被二分查找的特点是所有左边的数都比它小而右边的都比它大。所以用两个数组记录左边的最大值和右边的最小值即可。两遍遍历O(n)
回复

使用道具 举报

🔗
mhsasd 2019-4-2 04:55:03 | 只看该作者
全局:
mooc 发表于 2019-3-31 11:08
这道题不难的, 能被二分查找的特点是所有左边的数都比它小而右边的都比它大。所以用两个数组记录左边的最大 ...

实现了一下不对的。并不是所有的能找到的元素都一定要满足这个条件。
回复

使用道具 举报

🔗
chenchen628 2019-4-2 08:19:34 | 只看该作者
全局:
这题是不是可以直接对数组模拟一次没有target的二分搜索,但是不同于平时二分搜索的是,两边都搜,但是由之前执行过的搜索决定现在正在查看的数是不是valid。最后每个数只会被access一遍,所以是On。
回复

使用道具 举报

🔗
chenchen628 2019-4-2 08:38:15 | 只看该作者
全局:
chenchen628 发表于 2019-4-2 08:19
这题是不是可以直接对数组模拟一次没有target的二分搜索,但是不同于平时二分搜索的是,两边都搜,但是由之 ...

给个代码:
像楼上说的有几个需要clarify的地方,这个代码前提是是基于简单 (s+e)/2 二分查找,找到就停止。
输出的是找不到的数的下标。 如果需要输出具体哪些数字找不到,还要考虑有些数字出现多次,有些下标找不到有些下标找得到的情况,就需要最后过一遍数组,用一个hashset保存找不到的数。


  1. #include <iostream>
  2. #include <vector>

  3. using namespace std;

  4. #define INT_MIN 0x80000000
  5. #define INT_MAX 0x7fffffff

  6. class Solution {
  7. public:
  8.     vector<int> cantSearch(const vector<int>& nums) {
  9.         vector<bool> canSearch(nums.size(), false);
  10.         search(nums, 0, nums.size()-1, INT_MIN, INT_MAX, canSearch);
  11.         vector<int> res;
  12.         for (int i = 0; i < nums.size(); ++i) {
  13.             if (!canSearch[i]) res.push_back(i);
  14.         }
  15.         return res;
  16.     }
  17.    
  18. private:
  19.     void search(const vector<int>& nums, int s, int e,
  20.                 int min_val, int max_val, vector<bool>& canSearch) {
  21.         if (s > e || min_val > max_val) return;
  22.         int mid = (s + e) / 2;
  23.         if (nums[mid] < max_val && nums[mid] > min_val) canSearch[mid] = true;
  24.         search(nums, s, mid-1, min_val, min(max_val, nums[mid]), canSearch);
  25.         search(nums, mid+1, e, max(min_val, nums[mid]), max_val, canSearch);
  26.     }
  27. };
复制代码

评分

参与人数 1大米 +2 收起 理由
zdzapple + 2 给你点个赞!

查看全部评分

回复

使用道具 举报

🔗
mooc 2019-4-2 10:31:44 | 只看该作者
全局:
mhsasd 发表于 2019-4-2 04:55
实现了一下不对的。并不是所有的能找到的元素都一定要满足这个条件。

请举个例子
回复

使用道具 举报

🔗
chenchen628 2019-4-2 11:37:14 | 只看该作者
全局:

楼主在3楼的例子就行,[ 2, 7, 9, 10, 1 ]
这个例子里9是可以被查找到的,但是9右边有1比他小。
回复

使用道具 举报

🔗
mooc 2019-4-2 11:50:42 | 只看该作者
全局:
chenchen628 发表于 2019-4-2 11:37
楼主在3楼的例子就行,[ 2, 7, 9, 10, 1 ]
这个例子里9是可以被查找到的,但是9右边有1比他小。

题目里有一定能被找到的意思吧?
回复

使用道具 举报

🔗
mhsasd 2019-4-2 12:01:34 | 只看该作者
全局:

节选自144大神的例子:
Given nums: [22, 92, 25, 16, 29, 15, 49, 22, 38, 61]
Can't find: [16, 49, 25, 92, 15]

用你建议的方法没有一个找到。满足你的方法一定可以找到那个元素 但是并不是只有这样才可以找到那个元素。因为二分法找的时候跳了很多元素。
回复

使用道具 举报

🔗
mooc 2019-4-2 14:45:48 | 只看该作者
全局:
mhsasd 发表于 2019-4-2 12:01
节选自144大神的例子:
Given nums: [22, 92, 25, 16, 29, 15, 49, 22, 38, 61]
Can't find: [16, 49,  ...

我的方法确实有点逻辑漏洞,那就这么考虑。二分查找,每次减半对吧?一个target能被找到的条件是每次的二分后,你都得符合条件(你要么比middle值大,在右边,要么你比middle值小,我到左边去找你)用递归解决。这个思路总可以了吧?需要我贴代码吗?

我觉得面试的时候可以跟面试官讨论有没有重复值,如果没有重复值话, 我的方法肯定没问题

补充内容 (2019-4-2 14:55):
小伙伴觉得我的方法可行的话,加点大米哈 :)
回复

使用道具 举报

🔗
seamelody 2019-4-2 15:17:04 | 只看该作者
全局:
可以求一下這題的python代碼嗎?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表