Fork me on GitHub
posts - 176,  comments - 88,  trackbacks - 0

这篇文章主要是介绍剑指offer中的【位运算:二进制中1的个数】,【代码的完整性:数值的整数次方】,【代码的完整性:调整数组顺序使奇数位于偶数前面】的实现。

1. 位运算:二进制中1的个数,

题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

解题思路

把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。很多二进制的处理都可以用这种方法。

代码实现

        /// <summary>
        /// 新颖解法:
        /// 把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。
        /// 那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。
        /// 很多二进制的处理都可以用这种方法。
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static int NumberOf1(int n) {
            int count = 0;
            while (n != 0) {
                count++;
                n = (n - 1) & n;
            }
            return count;
        }
        /// <summary>
        /// 针对正整数(负数不会走)
        /// </summary>
        /// <param name="n"></param>
        /// <returns></returns>
        public static int SimpleNumberOf1(int n) {
            int count = 0;
            while (n > 0) { //右移的处理,
                if ((n & 1) == 1) {
                    count++;
                }
                n = n >> 1;
            }
            return count;
        }

想入非非:扩展思维,发挥想象

1. 熟悉位运算符:& (与)、 | (或) 、 ^ (异或)、~ (反运算符)、<< 二进制左移运算符、 >> 二进制右移运算符
2. 了解二进制(0b),八进制,十进制,十六进制(0x)

2.代码的完整性:数值的整数次方

题目描述

给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

解题思路

指数幂:a^n,当n是正数是a个n相乘,当n是负数是a个n相乘的倒数。

代码实现

        public static double Pow(double baseData, int exponent)
        {
            if (baseData == 0)
            {
                return 0;
            }

            bool isPositive = exponent > 0;//是否是正数
            exponent = isPositive ? exponent : -exponent;
            double result = 1;
            for (int i = 0; i < exponent; i++)
            {
                result = result * baseData;
            }
            result = isPositive ? result : (1 / result);
            return result;
        }

3.代码的完整性:调整数组顺序使奇数位于偶数前面

题目描述

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

解题思路

        public static int[] HandleArray(int[] array) {
            if (array == null) return null;
            int[] temp = new int[array.Length];
            int i = 0;
            //奇数
            foreach (var t in array) {
                if (t % 2 == 1) {
                    temp[i] = t;
                    i++;
                }
            }
            //偶数
            foreach (var t in array)
            {
                if (t % 2 == 0)
                {
                    temp[i] = t;
                    i++;
                }
            }
            return temp;
        }

下面的是不考略相对位置,只考虑效率,上面的解题效率是2n,下面的效率是n

        /// <summary>
        /// 不考略相对位置的
        /// </summary>
        /// <param name="array"></param>
        /// <returns></returns>
        public static int[] HandleArray2(int[] array)
        {
            if (array == null) return null;

            int left = 0;
            int right = array.Length - 1;
            while (left < right)
            {
                //奇数
                while (array[left] % 2 == 1)
                {
                    left++;
                }

                //偶数
                while (left < right && array[right] % 2 == 0)
                {
                    right--;
                }

                //交换
                if (left < right)
                {
                    var temp = array[left];
                    array[left] = array[right];
                    array[right] = temp;
                }

            }
            return array;
        }

 

posted on 2019-07-22 10:44 lingfeng95 阅读(...) 评论(...) 编辑 收藏