假设我有一个长度为A
的整数数组N
,我也有一个整数L
< = N
。
我想找的是范围[0,L-1],[1,L],[2,L + 1] ...... [NL,N-1]
(如从左到右的长度为L
的移动窗口)
我的算法现在是O(N lg N),其中O(N lg N)预处理:
A[0...L-1]
保存在多集S
中,并按顺序将该数字存储在队列Q
中。 [0,L-1]的最小值只是S
的第一个元素。 O(N lg N)Q
的第一个元素,在S
中找到此元素并将其删除。然后在A[L]
中推送S
。 [1,L]的最小值只是S
的第一个元素。 O(lg N)总计为O(N lg N)。
我想知道是否有任何算法可以达到以下要求:
我对RMQ做了一些研究,我发现最近的方法是使用稀疏表来实现O(1)查询时间但是O(N lg N)预处理时间。 reduce RMQ to LCA问题可以满足要求但需要对数组A
进行一些限制的另一种方法。
那么,在A
没有限制的情况下,解决我的问题时可以满足要求吗?
答案 0 :(得分:2)
是的,请使用deque。我们将保持元素按升序排序,因此对于当前位置[i - L + 1, i]
,第一个元素始终是i
中的最小元素。我们不会保留实际元素,但他们的位置。
d = empty deque
for i = 0 to n-1:
// get rid of too old elements
while !d.empty && i - d.front + 1 > L:
d.pop_front()
// keep the deque sorted
while !d.empty && A[d.back] > A[i]
d.pop_back()
d.push_back(i)
// A[d.front] is the minimum in `[i - L + 1, i]
由于每个元素最多进入和离开一次双端队列,因此O(n)
。//
// ViewController.swift
// MobileAppDemo
//
// Created by Mikko Hilpinen on 27.10.2016.
// Copyright © 2016 Mikkomario. All rights reserved.
//
import UIKit
import FBSDKCoreKit
import FBSDKLoginKit
import Firebase
import FirebaseAuth
import SwiftKeychainWrapper
fileprivate struct RegisterInfo
{
let email: String
let password: String
}
class SignInVC: UIViewController
{
@IBOutlet weak var emailField: UITextField!
@IBOutlet weak var passwordField: UITextField!
override func viewDidLoad()
{
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool)
{
if User.currentUserId != nil
{
print("AUTH: USING EXISTING KEYCHAIN")
User.startTrackingCurrentUser()
//performSegue(withIdentifier: "ToFeed", sender: nil)
}
else
{
print("AUTH: NO EXSTING KEYCHAIN")
}
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
print("AUTH: Preparing for segue \(segue.identifier)")
if let registrationVC = segue.destination as? RegisterVC
{
print("AUTH: Found registration VC")
if let info = sender as? RegisterInfo
{
print("AUTH: Sending email (\(info.email)) and password (\(info.password.characters.count) chars) information: ")
registrationVC.setBaseInfo(email: info.email, password: info.password)
}
}
}
@IBAction func signInButtonPressed(_ sender: UIButton)
{
if let email = emailField.text, let password = passwordField.text
{
FIRAuth.auth()?.signIn(withEmail: email, password: password)
{
(user, error) in
if let error = error
{
// TODO: Handle other errors here as well
switch FIRAuthErrorCode(rawValue: error._code)!
{
case .errorCodeUserNotFound:
print("AUTH: USER NOT FOUND -> CREATING NEW USER")
print("AUTH: Sending email \(email) and password \(password.characters.count) characters")
self.performSegue(withIdentifier: "RegisterUser", sender: RegisterInfo(email: email, password: password))
default: print("AUTH: ERROR IN EMAIL LOGIN \(error)") // TODO: Inform user
}
}
else
{
print("AUTH: EMAIL AUTH SUCCESSFUL")
User.currentUserId = user?.uid
User.startTrackingCurrentUser()
self.performSegue(withIdentifier: "ToFeed", sender: nil)
}
}
}
// TODO: Inform user that the field contents are missing
}
fileprivate func firebaseAuth(with credential: FIRAuthCredential)
{
if FIRAuth.auth() == nil
{
print("AUTH: NO AUTH SERVICE AVAILABLE")
}
FIRAuth.auth()?.signIn(with: credential)
{
(user, error) in
if let error = error
{
print("AUTH: UNABLE TO AUTHENTICATE TO FIREBASE")
print("AUTH: \(error)")
}
else
{
if let user = user
{
print("AUTH: SUCCESSFULLY AUTHENTICATED WITH FIREBASE")
// Updates current user data
var userName = "User"
var image: UIImage?
if let retrievedName = user.displayName
{
userName = retrievedName
}
if let retrievedImageUrl = user.photoURL
{
if let data = try? Data(contentsOf: retrievedImageUrl)
{
image = UIImage(data: data)
}
}
User.post(uid: user.uid, provider: user.providerID, userName: userName, image: image)
{
user in
User.currentUser = user
User.startTrackingCurrentUser()
self.performSegue(withIdentifier: "ToFeed", sender: nil)
}
}
}
}
}
}
。