我编写了代码来反转具有时间复杂度的数组:O(n)。
有更快的方法吗?
我的代码:
void reverseArray(int arr[], int start, int end){
int temp;
if(start >= end)
return;
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
reverseArray(arr, start+1, end-1);
}
答案 0 :(得分:12)
字面上颠倒内存中的元素不能比O(n)更快地完成。但是,您可以创建一个包装类来反转索引数组。所以,实际上你不会反转数组,而只能向后访问元素。
你拥有的代码是O(n),但由于递归而很糟糕。让它平坦,你会体验到一些好处。
public static void reverseArray(int arr[], int start, int end)
{
int len = end - start;
if(len <= 0) return;
int len2 = len >> 1;
int temp;
for (int i = 0; i < len2; ++i)
{
temp = arr[start + i];
arr[start + i] = arr[end - i - 1];
arr[end - i - 1] = temp;
}
}
答案 1 :(得分:4)
您使用的递归速度不如循环快。你仍然是O(n),但使用循环的时间更快。类似的东西:
static void reverseArray(int arr[]){
for (int start=0,end=arr.length-1;start<=end;start++,end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
对于类似这样的事情,你最好使用Java库中提供的方法来做到这一点。
答案 2 :(得分:4)
你可以使用一些中介功能:
int rev(int i) {
return arr.length - i - 1;
}
//...
arr[rev(i)] = 5; // reverse reference
答案 3 :(得分:2)
如果你使用静态数组,因为你需要访问每个元素一次才能反转它,所以没有比n更小的复杂性。
但是,如果您使用双重链接列表,那么通过定义,您可以访问两个方向的元素。从头到尾以及从尾到头,因为在使用的Node类中有双指针。因此,甚至不需要反向,,而是在需要时从尾部到头部进行迭代。
答案 4 :(得分:0)
递归与迭代。函数调用(递归)成本周期。因此,对于这个解决方案,我会采用迭代方法。其他需要注意的事项是:偶数/奇数大小的数组,空数组,只有1项的数组。未经测试的解决方案是:
void reverseArray(int arr[]){
//check input
if(arr.length <= 1){
return;
}
int arrLength = arr.length;
int swpIndex;
for (int i = 0; i < arrLength / 2 - 1; i++){
swpIndex = arrLength - i - 1;
swp = arr[i];
arr[i] = arr[swpIndex];
arr[swpIndex] = swp;
}
}
它存储了一些值,因此它确实避免了重复(即额外的循环)。它还会检查不需要反转的数组。