有人能给我一个具有平方根(n)时间复杂度的算法的例子。平方根时间复杂度甚至意味着什么?
答案 0 :(得分:19)
O(N^(1/2))
评估,其中输入的大小为N. O(sqrt(n))
时间的算法的示例,Grover的算法需要花费很长时间。 Grover's algorithm是一种量子算法,用于在O(sqrt(n))
时间内搜索n个条目的未排序数据库。 让我们举一个例子来了解如果出现问题,我们如何才能达到O(sqrt(N))
运行时复杂性。这将是详细的,但有趣的是要理解。 (以下示例,在回答此问题的上下文中,取自Coding Contest Byte: The Square Root Trick,非常有趣的问题和有趣的技巧,以达到O(sqrt(n))
复杂度)
给定A,包含n个元素数组,实现点更新和范围求和查询的数据结构。
天真的解决方案使用数组。更新(数组索引访问)需要O(1)
时间,范围总和需要O(hi - lo) = O(n)
(从开始索引到结束索引迭代并累加)。
query(2, 14) = A[2] + A[3]+ (A[4] + A[5] + A[6] + A[7]) + (A[8] + A[9] + A[10] + A[11]) + A[12] + A[13] + A[14] ;
query(2, 14) = A[2] + A[3] + S[1] + S[2] + A[12] + A[13] + A[14] ;
query(2, 14) = 0 + 7 + 11 + 9 + 5 + 2 + 0;
query(2, 14) = 34;
def update(S, A, i, k, x):
S[i/k] = S[i/k] - A[i] + x
A[i] = x
def query(S, A, lo, hi, k):
s = 0
i = lo
//Section 1 (Getting sum from Array A itself, starting part)
while (i + 1) % k != 0 and i <= hi:
s += A[i]
i += 1
//Section 2 (Getting sum from Slices directly, intermediary part)
while i + k <= hi:
s += S[i/k]
i += k
//Section 3 (Getting sum from Array A itself, ending part)
while i <= hi:
s += A[i]
i += 1
return s
O(sqrt(n))
时间复杂度查询。答案 1 :(得分:4)
有很多情况。 这些是根(n)复杂性可以解决的少数问题[也可能更好]。
您将面临许多需要使用sqrt(n)
复杂性算法的问题。
sqrt(n)复杂度意味着if the input size to your algorithm is n then there approximately sqrt(n) basic operations ( like **comparison** in case of sorting). Then we can say that the algorithm has sqrt(n) time complexity.
让我们分析第三个问题,这一点很清楚。
let's n= positive integer. Now there exists 2 positive integer x and y such that
x*y=n;
Now we know that whatever be the value of x and y one of them will be less than sqrt(n). As if both are greater than sqrt(n)
x>sqrt(n) y>sqrt(n) then x*y>sqrt(n)*sqrt(n) => n>n--->contradiction.
因此,如果我们检查2到sqrt(n)那么我们将考虑所有因素(1和n是微不足道的因素)。
int n;
cin>>n;
print 1,n;
for(int i=2;i<=sqrt(n);i++) // or for(int i=2;i*i<=n;i++)
if((n%i)==0)
cout<<i<<" ";
注意:您可能认为不考虑重复,我们也可以通过从1循环到n来实现上述行为。是的,但是谁想要运行一个可以在O(n)中的O(sqrt(n))中运行的程序。我们总是寻找最好的。
阅读Cormen一书算法简介。
我还会请求您阅读以下stackoverflow问题和答案,他们会清除所有疑问:)
答案 2 :(得分:4)
素数
正如其他一些答案中所提到的,与素数相关的一些基本事物需要O(sqrt(n))时间:
下面我提到两种先进的算法,它们的复杂性也带有sqrt(n)项。
MO&#39>算法
尝试此问题:Powerful array
我的解决方案:
#include <bits/stdc++.h>
using namespace std;
const int N = 1E6 + 10, k = 500;
struct node {
int l, r, id;
bool operator<(const node &a) {
if(l / k == a.l / k) return r < a.r;
else return l < a.l;
}
} q[N];
long long a[N], cnt[N], ans[N], cur_count;
void add(int pos) {
cur_count += a[pos] * cnt[a[pos]];
++cnt[a[pos]];
cur_count += a[pos] * cnt[a[pos]];
}
void rm(int pos) {
cur_count -= a[pos] * cnt[a[pos]];
--cnt[a[pos]];
cur_count -= a[pos] * cnt[a[pos]];
}
int main() {
int n, t;
cin >> n >> t;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
for(int i = 0; i < t; i++) {
cin >> q[i].l >> q[i].r;
q[i].id = i;
}
sort(q, q + t);
memset(cnt, 0, sizeof(cnt));
memset(ans, 0, sizeof(ans));
int curl(0), curr(0), l, r;
for(int i = 0; i < t; i++) {
l = q[i].l;
r = q[i].r;
/* This part takes O(n * sqrt(n)) time */
while(curl < l)
rm(curl++);
while(curl > l)
add(--curl);
while(curr > r)
rm(curr--);
while(curr < r)
add(++curr);
ans[q[i].id] = cur_count;
}
for(int i = 0; i < t; i++) {
cout << ans[i] << '\n';
}
return 0;
}
查询缓冲
尝试此问题:Queries on a Tree
我的解决方案:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10, k = 333;
vector<int> t[N], ht;
int tm_, h[N], st[N], nd[N];
inline int hei(int v, int p) {
for(int ch: t[v]) {
if(ch != p) {
h[ch] = h[v] + 1;
hei(ch, v);
}
}
}
inline void tour(int v, int p) {
st[v] = tm_++;
ht.push_back(h[v]);
for(int ch: t[v]) {
if(ch != p) {
tour(ch, v);
}
}
ht.push_back(h[v]);
nd[v] = tm_++;
}
int n, tc[N];
vector<int> loc[N];
long long balance[N];
vector<pair<long long,long long>> buf;
inline long long cbal(int v, int p) {
long long ans = balance[h[v]];
for(int ch: t[v]) {
if(ch != p) {
ans += cbal(ch, v);
}
}
tc[v] += ans;
return ans;
}
inline void bal() {
memset(balance, 0, sizeof(balance));
for(auto arg: buf) {
balance[arg.first] += arg.second;
}
buf.clear();
cbal(1,1);
}
int main() {
int q;
cin >> n >> q;
for(int i = 1; i < n; i++) {
int x, y; cin >> x >> y;
t[x].push_back(y); t[y].push_back(x);
}
hei(1,1);
tour(1,1);
for(int i = 0; i < ht.size(); i++) {
loc[ht[i]].push_back(i);
}
vector<int>::iterator lo, hi;
int x, y, type;
for(int i = 0; i < q; i++) {
cin >> type;
if(type == 1) {
cin >> x >> y;
buf.push_back(make_pair(x,y));
}
else if(type == 2) {
cin >> x;
long long ans(0);
for(auto arg: buf) {
hi = upper_bound(loc[arg.first].begin(), loc[arg.first].end(), nd[x]);
lo = lower_bound(loc[arg.first].begin(), loc[arg.first].end(), st[x]);
ans += arg.second * (hi - lo);
}
cout << tc[x] + ans/2 << '\n';
}
else assert(0);
if(i % k == 0) bal();
}
}
答案 3 :(得分:0)
def obtenerTexto(frame):
#here i have the text always
h, w, c = imagen.shape
hini = int(0.84*h)
wfin = int(0.45*w)
text = frame[hini:h, 0:wfin]
#resize the imagen and i make a threshold
resize = cv2.resize(im, None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC)
gray = cv2.cvtColor(resize, cv2.COLOR_BGR2GRAY)
retval, chat = cv2.threshold(gray,150,255,cv2.THRESH_BINARY)
#pytesseract
textoNuevo = pytesseract.image_to_string(chat).split("\n")
#Video Capture
video_file = 'videos/Video.flv'
cap = cv2.VideoCapture(video_file)
# Properties
font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 0.6
color = (0,255,0)
thickness = 2
height_prop = cv2.CAP_PROP_FRAME_HEIGHT
fps_prop = cv2.CAP_PROP_FPS
while(cap.isOpened()):
ret, frame = cap.read()
if ret == True:
# Text position
height = int(cap.get(height_prop))
position = (50, height - 50)
# Frames per second
fps = "{0:.2f}".format(cap.get(fps_prop))
text = "FPS: " + fps
# Put text
cv2.putText(frame, text, position, font, font_scale, color, thickness)
# Serching text and OCR
obtener_texto(frame)
# Display
height , width , layers = frame.shape
new_h=int(height/2)
new_w=int(width/2)
resize = cv2.resize(frame, (new_w, new_h))
cv2.imshow("Video", resize)
# Exit?
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
# Release everything if job is finished
cap.release()
cv2.destroyAllWindows()
O(N ^ 1/2)因为对于给定的n值,您只需要查找n是否可以被2整除为根。
答案 4 :(得分:0)
感谢Samme Bae,该版本的性能更高,能给我带来启发。 ?
function isPrime(n) {
if (n <= 1)
return false;
if (n <= 3)
return true;
// Skip 4, 6, 8, 9, and 10
if (n % 2 === 0 || n % 3 === 0)
return false;
for (let i = 5; i * i <= n; i += 6) {
if (n % i === 0 || n % (i + 2) === 0)
return false;
}
return true;
}
isPrime(677);
答案 5 :(得分:0)
此链接为O()(即O(sqrt n)时间复杂度)提供了非常基本的初学者理解。这是视频中的最后一个示例,但我建议您观看整个视频。
https://www.youtube.com/watch?v=9TlHvipP5yA&list=PLDN4rrl48XKpZkf03iYFl-O29szjTrs_O&index=6
视频中O()的最简单示例,即O(sqrt n)时间复杂度算法为:
p = 0;
for(i = 1; p <= n; i++)
{
p = p + i;
}
先生。 Abdul Bari以对数据结构和算法的简单解释而闻名。