给定一个可以旋转的排序数组,以最小的时间复杂度在其中找到一个元素.
例如:数组内容可以是[8,1,2,3,4,5].假设您在其中搜索8.
我需要在N个位置向右和向左移动一个数组.
在我转移到的一侧弹出的物品必须回到另一侧.
向右移动13:
[0,1,2,3,4,5,6,7,8,9] -> [7,8,9,0,1,2,3,4,5,6]
Run Code Online (Sandbox Code Playgroud)
向左移15:
[0,1,2,3,4,5,6,7,8,9] -> [5,6,7,8,9,0,1,2,3,4]
Run Code Online (Sandbox Code Playgroud)
此操作将发生数百万次,并且必须非常快.
我目前的实施如下.请查看并建议是否有一些优化要做.
if (shift > 0)
{
int offset = array.Length % shift;
if (offset > 0)
{
byte[] temp = new byte[offset];
if (!right)
{
Array.Copy(array, temp, offset);
Array.Copy(array, offset, array, 0, array.Length - offset);
Array.Copy(temp, 0, array, array.Length - offset, temp.Length);
}
else
{
Array.Copy(array, array.Length - offset, temp, 0, offset);
Array.Copy(array, 0, array, offset, array.Length - offset);
Array.Copy(temp, 0, array, 0, temp.Length);
}
}
}
Run Code Online (Sandbox Code Playgroud)
作为一个关于它将被转移多少的提示(但我怀疑它可以导致优化):
- …Run Code Online (Sandbox Code Playgroud) 我有以下问题要测试:
通过k步向右旋转n个元素的数组.
例如,当n = 7且k = 3时,阵列[1,2,3,4,5,6,7]旋转到[5,6,7,1,2,3,4].您知道解决此问题的方式有多少种?
我的中间阵列解决方案:
使用Space is O(n)和time O(n),我可以创建一个新数组,然后将元素复制到新数组.然后使用更改原始数组System.arraycopy().
public void rotate(int[] nums, int k) {
if(k > nums.length)
k=k%nums.length;
int[] result = new int[nums.length];
for(int i=0; i < k; i++){
result[i] = nums[nums.length-k+i];
}
int j=0;
for(int i=k; i<nums.length; i++){
result[i] = nums[j];
j++;
}
System.arraycopy( result, 0, nums, 0, nums.length );
}
Run Code Online (Sandbox Code Playgroud)
但是,有更好的方法可以通过空间中的气泡旋转(如气泡排序)来实现O(1吗?
我试图只使用一个1D阵列,通过n个位置进行数组的圆形左移.我可以在两个数组中完成,但我还没弄明白如何使用它.请提出你的建议
是否存在在圆形的int数组上执行左移的现有方法?
具体来说,给定一个包含4个项目{1,2,3,4}且移位量为2 的数组,我想要一个方法将前两个字母移动到数组的后面,使它看起来如下:{3,4,1,2}.
这个算法可以将圆形数组移动一个吗?
algShiftByOne(Array)
{
temp=array[0];
i=1
while(i < Array.length - 1) // Loop from 1 up to array.length == last index
{
// If there is no exception i assume it copies value from
// initial array starting from 1 up to array.length
Array[i - 1] = Array[i];
i++;
}
Array[Array.length]=temp;
}
Run Code Online (Sandbox Code Playgroud)