奇技淫巧(一)—— 不分奇偶讨论倒置数组

先看例子:

偶数  

a[6]:  0 , 1 , 2    |     3 , 4 , 5             //MaxSize=6

则应该 i < 6/2=3; 即  0  1   2    交换   3   4   5  

奇数

a[7]:  0 , 1 , 2 ,  3  , 4 , 5  , 6            //MaxSize=7

则应该  i < 7/2=3.5;

a[3]———a[7-3-1] = a[3]

所以a[3]会跟自己交换一次:即  0  1   2   3     交换   3   4   5    6

正确:

int temp;
for(int i=0; i<MaxSize/2; i++){
    temp = a[i];
    a[i] = a[MaxSize-i-1];
    a[MaxSize-i-1] = temp;
}

综上,不分奇偶,边界设为MaxSize/2即可

 

for(int i = 0;i < MaxSize/2;i++)

 

PS:这应该作为结论记住。

若钻牛角一点,就是不想多做奇数长度中间位置的交换怎么办?

即上面提到的a[7]的a[3]跟a[3]自己交换。

① 边界分奇偶数讨论设置

int bound;
int temp;
if(MaxSize%2 == 0)
  bound = MaxSize/2;
else
  bound = (MaxSize-1)/2;        
for(int i = 0;i < bound;i++)
{
  temp = a[i];
  a[i] = a[MaxSize-1-i];       //由0+5=1+4=2+3=5可以归纳出对称位置为MaxSize-1-i
  a[MaxSize-1-i] = temp;
}

② 边界设为i <= MaxSize/2-1

int temp;
for(int i=0;i <= MaxSize/2-1;i++)
{
  temp = a[i];
  a[i] = a[MaxSize-1-i];       //由0+5=1+4=2+3=5可以归纳出对称位置为MaxSize-1-i
  a[MaxSize-1-i] = temp;
}

 

这对于偶数长度一样是适用的:如a[6],则 i <= MaxSize/2-1 = 2,i <= 2,同样适用的。

③ 既稳妥又思路清晰的办法:左右双指针法

// 多用了一个存储空间j而已
int temp;
for(int i = 0,int j = MaxSize-1;i < j ;i++,j--)   //注意,若用i <= j则奇数时多交换了一次
{
  temp = a[i];
  a[i] = a[j];      
  a[j] = temp;   
}

 

 ④ 还是使用i < MaxSize/2,但是在swap上做”减枝“

for(int i=0; i<MaxSize/2; i++){
    swap(a,i,MaxSize-1-i);
}
public void swap(int[] nums, int i, int j){
    // 进行判断,如果是自己跟自己,则不用交换
    if(i != j ){      
        nums[i] = nums[i]^nums[j];
        nums[j] = nums[i]^nums[j];
        nums[i] = nums[i]^nums[j];
    }
}

最后,综合来看,还是使用i < MaxSize/2比较好,多交换一个,代码简洁,记忆负担小:

for(int i=0; i<MaxSize/2; i++){
    a[i] = a[i]^a[MaxSize-1-i];
    a[MaxSize-1-i] = a[i]^a[MaxSize-1-i];
    a[i] = a[i]^a[MaxSize-1-i];
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值