我正在LeetCode上解决一个问题:
给定一个未排序的整数数组
nums,返回最长连续元素序列的长度。您必须编写一个及时运行的算法O(n)。因此对于nums=[100,4,200,1,3,2],输出为4。
解决这个问题的Union Find解决方案如下:
class Solution {
public:
vector<int> parent, sz;
int find(int i) {
if(parent[i]==i) return i;
return parent[i]=find(parent[i]);
}
void merge(int i, int j) {
int p1=find(i);
int p2=find(j);
if(p1==p2) return;
if(sz[p1]>sz[p2]) {
sz[p1]+=sz[p2];
parent[p2]=p1;
} else {
sz[p2]+=sz[p1];
parent[p1]=p2;
}
}
int longestConsecutive(vector<int>& nums) {
sz.resize(nums.size(),1);
parent.resize(nums.size(),0);
iota(begin(parent),end(parent),0);
unordered_map<int, int> m;
for(int i=0; i<nums.size(); i++) {
int n=nums[i];
if(m.count(n)) continue;
if(m.count(n-1)) merge(i,m[n-1]);
if(m.count(n+1)) merge(i,m[n+1]);
m[n]=i; …Run Code Online (Sandbox Code Playgroud) 我在现场面试中被问到以下问题:
当字符串中的每个字母都以大写和小写形式出现时,该字符串被认为是“平衡的”。例如,
CATattac是平衡的(a,c,t在两种情况下都出现),而Madam不是(a,d只出现在小写)。编写一个函数,给定一个字符串,返回该字符串的最短平衡子字符串。例如:
“azABaabza”应该返回“ABaab”
“TacoCat”应该返回-1(不平衡)
“AcZCbaBz”应该返回整个字符串
用蛮力方法做它是微不足道的 - 计算所有子串对,然后检查它们是否平衡,同时跟踪最小一个的大小和起始索引。
我该如何优化?我有一种强烈的感觉,它可以通过滑动窗口/双指针方法来完成,但我不确定如何。什么时候更新滑动窗口的指针?
编辑:删除滑动窗口标签,因为这不是滑动窗口问题(如评论中所述)。
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
vector<int> parent, sz;
int find(int i) {
if(parent[i]==i) return i;
return parent[i]=find(parent[i]);
}
void merge(int i, int j) {
int p1=find(i);
int p2=find(j);
if(p1==p2) return;
if(sz[p1]<sz[p2]) {
parent[p1]=p2;
sz[p2]+=sz[p1];
} else {
parent[p2]=p1;
sz[p1]+=sz[p2];
}
}
int main() {
vector<vector<int>> allowedSwaps={{0,4},{4,2},{1,3},{1,4}};
int n=5; //hard-code for now
sz.resize(n,1);
parent.resize(n);
iota(begin(parent),end(parent),0);
cout<<"Parents before: \n";
for(auto& e: parent)
cout<<e<<" ";
cout<<"\n";
for(vector<int>& currswap: allowedSwaps) {
merge(currswap[0],currswap[1]);
}
cout<<"Parents after: …Run Code Online (Sandbox Code Playgroud) 我正在尝试解决 BinarySearch.com 上的一个问题:
给定一个按升序排序的整数 nums 和一个整数 k 的列表,返回列表中的任意两个元素加起来是否为 k。您不能两次使用相同的元素。注意:数字可以是负数或 0。这应该在
O(1)空格中完成。
所以对于nums = [1, 3, 5, 8]和k = 6,答案应该是true。
我知道它可以使用两个指针来完成,但我正在学习二进制搜索,所以我想出了以下逻辑:
bool solve(vector<int>& nums, int k) {
for(int i=0; i<nums.size(); i++) {
auto loc=lower_bound(begin(nums), end(nums), k-nums[i]);
if(loc!=nums.end()) {
if(distance(nums.begin(), loc)!=i && *loc+nums[i]==k) return true;
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
它被接受了,但时间复杂度是多少?我不确定是O(NlogN)因为我O(logN)对 中的每个值运行二分搜索(算法)nums,还是应该是O(N^2)因为当if条件为真时,我使用distance(),据我所知,这O(n)本身就是一个操作。