剑指offer(十二,十三) 数值的整数次方,调整数组顺序使奇数位于偶数前面

1.数值的整数次方

***时间限制:1秒 空间限制:32768K ***
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

标准的快速幂。。。注意base为0 return 0,我用JS抛出错误在oj上错了 QAQ
还有就是负数的情况,变正,然后倒回来。
其实这个base是double类型,C++里面的话不能直接比较,需要写个abs

    boolean equal(double num1,double num2){
        if(num1-num2>-0.000001&&num1-num2<0.000001)
            return true;
        else
            return false;
    }

我用js写就先不考虑这个问题了。
还有就是快速幂的思想了,其实就是二进制化再重组答案,重组答案的时候底数是新base。
时间复杂度是二进制的长度,也就是logn。(参考二叉树的深度)

/*
2^11 = 2^1 * 2^2 * 2^8
2^1011 = 1* 2^0001 + 1* 2^0010 + 0*2^0000 +1* 2^1000

11 = 1011(2)
1*x^8 + 0*x^4 + 1*x^2 + 1*x
x是底数,分解二进制 -> 根据新底数重组答案(底数不是2了)
*/
function Power(base, exponent)
{
    p = exponent;
    if(base==0) return 0;
    else if(p==0) return 1;
    else if(p<0)
        p = -p;//变正
    var ans = 1;
    while(p) {
        // console.log(p);
        if(p&1) {
            ans *= base;
        }
        base*=base;//相应的基数自乘
        p = p>>1;//遍历二进制下的每一位
    }
    return exponent>0?ans:1/ans;
}

console.log(Power(2, 3));


2.调整数组顺序使奇数位于偶数前面

时间限制:1秒空间限制:32768K
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

看到这道题我就想到了排序的思想,这道题也就是排序的变种,只不过这里重新制定了排序的规则而已,不是常规的降序或者升序。

两个方向,时间换空间,空间换时间。

时间换空间

可以利用插排思想和冒泡排序思想,时间换空间下也有两种方法。

1.在原数组上操作,插入排序的思想,制定两个指针,i和j,i从前面扫面找到第一个偶数,j从i+1开始扫描找到第一个奇数,把i.......j-1往后移动一个位置,提前保存好tmp=array[j],把j位置上的tmp插到i位置,完成交换。
eg:
1 2 4 6 7
i j
->交换后
1 7 2 4 6,因为j是i+1的,如果i找不到j也就找不到了(i会到len),利用这个判断边界。

function reOrderArray(array)
{
    if(array.length==0) return [];
    var len = array.length;
    var i = 0;
    while(i<len) {
        while (i < len && judge_q(array[i])) i++;
        var j = i + 1;
        while (j < len && !judge_q(array[j])) j++;
        if (j < len) {
            var tmp = array[j];
            for (var k = j; k > i; k--) {
                array[k] = array[k - 1];
            }
            array[i] = tmp;
        }else {
            break;
        }
    }
    return array;
}

function judge_q(a) {
    if(a&1) return true;
    else return false;
}

var b = [1,2,4,6,7];
console.log(reOrderArray(b));

时间复杂度O(N^2),当然空间上省了很多。(没开第三方数组)

2.理解上面的,肯定就会想到用冒泡排序的思想来做了

//C++
for (int i = 0; i < array.size();i++)
{
    for (int j = array.size() - 1; j>i;j--)
    {
        if (array[j] % 2 == 1 && array[j - 1]%2 == 0) //前偶后奇交换
        {
            swap(array[j], array[j-1]);
        }
    }
}

也是O(N^2)的复杂度

空间换时间

O(n)线性时间复杂度,空间上多开一个数组。

function reOrderArray(array)
{
    var ans_q = [];
    var ans_o = [];
    for(var i = 0; i <array.length; i++) {
        if(array[i]&1) {
            ans_q.push(array[i]);
        }
        else {
            ans_o.push(array[i]);
        }
    }
    return ans_q.concat(ans_o);
}
posted @ 2018-02-01 06:23  Lawliet__zmz  阅读(158)  评论(0编辑  收藏  举报