C++ 数组:左旋转|破解编码面试黑客等级-(因超时而终止)
我是一个相当普通的程序员,正试图通过黑客排名网站提供的各种挑战来提高我的技能。我试图解决这个数组左旋转算法,并且能够通过每个测试用例,除了最后一个是一个大的数字文件。在做了一些研究之后,我发现由于超时错误导致的终止是由于算法不够有效,我想黑客等级对每个测试用例都有某种时间限制或速度测试,我的算法不够快。下面我提供了我提出的问题和我实现的代码,如果有人能帮我减少优化这个算法(解释!),为什么我的算法比较慢,我会非常感激。多爱你C++ 数组:左旋转|破解编码面试黑客等级-(因超时而终止),c++,arrays,algorithm,C++,Arrays,Algorithm,我是一个相当普通的程序员,正试图通过黑客排名网站提供的各种挑战来提高我的技能。我试图解决这个数组左旋转算法,并且能够通过每个测试用例,除了最后一个是一个大的数字文件。在做了一些研究之后,我发现由于超时错误导致的终止是由于算法不够有效,我想黑客等级对每个测试用例都有某种时间限制或速度测试,我的算法不够快。下面我提供了我提出的问题和我实现的代码,如果有人能帮我减少优化这个算法(解释!),为什么我的算法比较慢,我会非常感激。多爱你 说明: 对大小为n的数组执行左旋转操作会将数组的每个元素向左移动1个
说明:
对大小为n的数组执行左旋转操作会将数组的每个元素向左移动1个单位。例如,如果对数组[1,2,3,4,5]执行两次左旋转,则该数组将变为[3,4,5,1,2]
给定一个由n个整数和一个数字d组成的数组,在该数组上执行d次左旋转。然后将更新后的数组打印为一行空格分隔的整数
输入格式
第一行包含两个空格分隔的整数,分别表示n(整数的数量)和d(必须执行的左旋转的数量)的值。 第二行包含n个空间分隔的整数,描述数组初始状态的各个元素。
约束条件
1这是我更有效的算法- 反转算法 要在
k
位置旋转数组(将k
移动到n
元素的左侧),我们可以执行以下操作:
arr[0…k-1]
这是O(k)
arr[k…n-1]
是O(n-k)
arr[0…n]
,即O(n)
O(n)
,空间复杂度为常数
你必须注意像k>=n
,k<0
等情况
void leftRotate(vector<int>& arr, int k)
{
int n = (int)arr.size();
if(k >= n) k = k % n;
reverse(arr.begin(), arr.begin() + k);
reverse(arr.begin() + k, arr.end());
reverse(arr.begin(), arr.end());
}
void leftRotate(向量和arr,int k)
{
int n=(int)arr.size();
如果(k>=n)k=k%n;
反向(arr.begin(),arr.begin()+k);
反向(arr.begin()+k,arr.end());
反向(arr.begin(),arr.end());
}
希望有帮助 这是我更有效的算法- 反转算法 要在
k
位置旋转数组(将k
移动到n
元素的左侧),我们可以执行以下操作:
arr[0…k-1]
这是O(k)
arr[k…n-1]
是O(n-k)
arr[0…n]
,即O(n)
O(n)
,空间复杂度为常数
你必须注意像k>=n
,k<0
等情况
void leftRotate(vector<int>& arr, int k)
{
int n = (int)arr.size();
if(k >= n) k = k % n;
reverse(arr.begin(), arr.begin() + k);
reverse(arr.begin() + k, arr.end());
reverse(arr.begin(), arr.end());
}
void leftRotate(向量和arr,int k)
{
int n=(int)arr.size();
如果(k>=n)k=k%n;
反向(arr.begin(),arr.begin()+k);
反向(arr.begin()+k,arr.end());
反向(arr.begin(),arr.end());
}
希望有帮助 对我来说,这项任务听起来根本不需要执行旋转。您只需打印出结果,完全跳过旋转 基本上,您只需执行以下操作:
n
和d
d
数字仅此而已,我不认为你能比完全省略工作更有效率;-) 对我来说,这项任务听起来根本不需要执行旋转。您只需打印出结果,完全跳过旋转 基本上,您只需执行以下操作:
n
和d
d
数字仅此而已,我不认为你能比完全省略工作更有效率;-) 为什么不使用
std::rotate
?哦,天哪@PaulMcKenzie,我不知道有这样的事情!谢谢,所以muchI可能会错过一些明显的东西,但为什么要实现旋转函数呢?您只需读取输入并将其直接传递到输出即可。您应该只跳过存储在数组中并在最后打印的第一个n-d
数字?两个可能的改进是将时间复杂度从O(kn)降低到O(n)(下面有一个答案说明了如何实现)避免将std::vector复制到函数中-通过引用使用调用。为什么不使用std::rotate
?噢,我的天哪@PaulMcKenzie,我不知道有这样的事情!谢谢,所以muchI可能会错过一些明显的东西,但为什么要实现旋转函数呢?您只需读取输入并将其直接传递到输出即可。您应该只跳过存储在数组中并在最后打印的第一个n-d
数字?两个可能的改进是将时间复杂度从O(kn)降低到O(n)(下面有一个答案说明了如何实现)和避免将std::vector复制到函数中-使用引用调用。
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
vector<int> array_left_rotation(vector<int> a, int n, int k) {
int tmp=0,x=0;
while(x < k){
tmp = a[0];
for(int i=0; i < n; i++){
a[i]=a[i+1];
if(i+1 == n) a[i]= tmp;
}
x++;
}
return a;
}
int main(){
int n;
int k;
cin >> n >> k;
vector<int> a(n);
for(int a_i = 0;a_i < n;a_i++){
cin >> a[a_i];
}
vector<int> output = array_left_rotation(a, n, k);
for(int i = 0; i < n;i++)
cout << output[i] << " ";
cout << endl;
return 0;
}
void leftRotate(vector<int>& arr, int k)
{
int n = (int)arr.size();
if(k >= n) k = k % n;
reverse(arr.begin(), arr.begin() + k);
reverse(arr.begin() + k, arr.end());
reverse(arr.begin(), arr.end());
}