左边的k个数字是原来右边的,右边的n-k个数字是原来左边的。
其实就是先把整个array reverse了。然后把左边k个reverse 再把右边n-k个reverse。
k = 3, 1 2 3 4 5 6 7 ----> 5 6 7 1 2 3 4
private void rev(int [] num, int beg, int end) {
while(beg < end) {
int tmp = num[beg];
num[beg] = num[end];
num[end] = tmp;
beg ++;
end --;
}
}
public void rotate(int[] nums, int k) {
k = k % nums.length;
if(k <= 0) {
return;
}
rev(nums, 0, nums.length-1);
rev(nums, 0, k-1);
rev(nums, k, nums.length-1);
}
看到这个问题后我的第一印象是采用循环移位:
把字符用二进制表示,即0101的字符串,然后进行循环移位,这个是可行的,自己还去找了下循环移位如何实现,下面是c语言循环移位的一种实现:
假设串的长度是N,要循环移位k位,那么:
循环右移:(a>>k) | (a<<(N-k)) //即a先右移k位,然后再左移N-k位,然后进行或|运算就实现了循环右移。
循环左移:(a<<k) | (a>>(N-k)) //即a先左移k位,然后再右移N-k位,然后进行或运算就实现了循环左移
运算符 含义 描述
&按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
<<左移 用来将一个数的各二进制位全部左移N位,右补0
>>右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0
#define ROTATE_LEFT(x, s, n) ((x) << (n)) | ((x) >> ((s) - (n)))
#define ROTATE_RIGHT(x, s, n) ((x) >> (n)) | ((x) << ((s) - (n)))
下面是一个小的测试程序:
复制代码
#define ROTATE_LEFT(x, s, n) ((x) << (n)) | ((x) >> ((s) - (n)))
#define ROTATE_RIGHT(x, s, n) ((x) >> (n)) | ((x) << ((s) - (n)))
int main()
{
unsigned int a=0x12345678;
unsigned b=ROTATE_LEFT(a, 8 * sizeof(int), 4);
unsigned c=ROTATE_RIGHT(a, 8 * sizeof(int), 8);
printf("original :%08x\n",a);
printf("rot_left :%08x\n",b);
printf("rot_right:%08x\n",c);
return 0;
}
http://www.cnblogs.com/xkfz007/archive/2012/05/20/2510626.html