在具有重复项的排序数组中查找A [i] = i(Finding A[i]=i in a sorted array with duplicates)
给定一个可能重复的整数排序数组,你如何找到一个索引
i
,使得A[i]=i
这是我读过的一本编程书中的一个问题(Cracking the code interview)。 解决方案概述如下:
public static int magicFast(int[] array, int start, int end) { if (end < start || start < 0 || end >= array.length) { return -1; } int midlndex = (start + end) / 2; int midValue = array[midlndex]; if (midValue == midlndex) { return midlndex; } /* Search left */ int leftlndex = Math.min(midlndex - 1, midValue); int left = magicFast(array, start, leftlndex); if (left >= 0) { return left; } /* Search right */ int rightlndex = Math.max(midlndex + i, midValue); int right = magicFast(array, rightlndex, end); return right; }
作者没有评论时间复杂性。 然而,这似乎是O(n)解决方案,因为我们需要查看“中间”点的两侧,而不像数组元素不同的问题。 递归关系为T(n)= 2T(n / 2)+ c(c - 检查中间元素是否为答案的恒定时间)
这比简单的线性扫描更好吗? 这似乎过于复杂,只是为了实现线性时间效率。 我在这里错过了什么吗?
Given a sorted array of integers with possibly duplicates, how do you find an index
i
such thatA[i]=i
This is a problem in one of the programming books I read (Cracking the code interview). The solution is outlined as follows:
public static int magicFast(int[] array, int start, int end) { if (end < start || start < 0 || end >= array.length) { return -1; } int midlndex = (start + end) / 2; int midValue = array[midlndex]; if (midValue == midlndex) { return midlndex; } /* Search left */ int leftlndex = Math.min(midlndex - 1, midValue); int left = magicFast(array, start, leftlndex); if (left >= 0) { return left; } /* Search right */ int rightlndex = Math.max(midlndex + i, midValue); int right = magicFast(array, rightlndex, end); return right; }
The author does not comment on the time complexity. However, this seems to be O(n) solution since we need to look at both sides of the 'mid' point unlike the problem where array elements are distinct. The recurrence relation being T(n) = 2T(n/2) + c (c - constant time to check if the middle element is the answer)
How is this better than a simple linear scan then? This seems overly complicated just to achieve linear time efficiency. Am I missing something here?
原文:https://stackoverflow.com/questions/42599946
最满意答案
RSpec期望机制将与线程一起正常工作,如以下示例所示,该示例通过:
def foo(&block) block.call(42) end describe "" do it "" do l = lambda {} expect(l).to receive(:call).with(42) Thread.new { foo(&l) }.join end end
在继续之前,
join
等待线程完成。The RSpec expectations machinery will work fine with threads, as evidenced by the following example, which passes:
def foo(&block) block.call(42) end describe "" do it "" do l = lambda {} expect(l).to receive(:call).with(42) Thread.new { foo(&l) }.join end end
The
join
waits for the thread(s) to finish before going further.
相关问答
更多-
TCP/IP模型是一个________。[2023-10-02]
a -
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
您必须使用RSpec的yield yield匹配器之一 : describe SP do it "testing speak functionality can receive a block" do sp = SP.new expect { |b| sp.speak(&b) }.to yield_control end end You have to use one of RSpec's yield matcher: describe SP do it "testing sp ...
-
我会尝试这样的事情: let!(:name) { create(:name) } describe "when given a block" do before do allow(subject).to receive(:find_name_by_id).with(name.id).and_return(name) allow(name).to receive(:save).and_call_original end it "yields something" do ...
-
单元测试在try catch块中调用异步操作的getter(Unit Testing a getter that calls an async operation in a try catch block)[2022-02-13]
由于属性不是async兼容(这是一个明智的设计选择IMO),您可以采用Stephan Clearys博客文章中提到的IntializeXXXAsync模式。 模式的作用是让您调用初始化方法,该方法负责创建值。 如果失败,您可以默认返回default(T) ,在您的情况下,字符串只是null ,并在其上断言: public class FuzzyPickles : INotifyPropertyChanged { public FuzzyPickles(IPie pieMaker) { ... -
我经常这样做 a = 1 b.go { a = 2} a.should == 2 I usually do something like a = 1 b.go { a = 2} a.should == 2
-
RSpec期望机制将与线程一起正常工作,如以下示例所示,该示例通过: def foo(&block) block.call(42) end describe "" do it "" do l = lambda {} expect(l).to receive(:call).with(42) Thread.new { foo(&l) }.join end end 在继续之前, join等待线程完成。 The RSpec expectations machinery wil ...
-
测试是否已调用join(Test if join has been called)[2023-03-06]
在线程的while循环中调用joinable()函数来测试线程上是否有连接请求或者是否存在我目前不考虑的任何副作用是否合法? 除非您使用某种手动同步,否则这可能会导致数据争用(因此未定义的行为)。 std::thread::join()是一个非const成员函数,因此对它的任何调用都可能与同一对象的成员函数的任何其他调用同时发生冲突 ,并导致数据竞争。 因此,如果一个线程调用std::thread::join()而另一个线程同时在同一个对象上调用std::thread::joinable() ,则会出现数据 ... -
同步块后面(Behind Synchronized Block)[2022-02-13]
是的,它有点特别。 wait释放在synchronized block中获取的锁,并挂起它的thread (获取锁的线程),这意味着其他线程将被允许获取锁并修改状态。 现在notify或notifyAll会唤醒睡眠中的线程并重新获取lock Yes, it is somehow special. wait releases the lock acquired in the synchronized block and and suspends it's thread (the thread that acq ... -
我使用的一种常见模式: block_called = false get_data_with_timeout(1) do block_called = true end block_called.should be_true A common pattern that I use: block_called = false get_data_with_timeout(1) do block_called = true end block_called.should be_true