写点什么

【算法】剑指 offer- 调整数组顺序 && 数组出现超过一半的数字

作者:芒果酱
  • 2022-10-16
    广东
  • 本文字数:2314 字

    阅读完需:约 1 分钟

调整数组顺序

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


https://www.nowcoder.com/practice/beb5aa231adc45b2a5dcc5b62c93f593?tpId=13&tqId=11166&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking




奇数在前偶数在后 &&相对顺序可以改变的情况:


方法 1:遍历两次数组,第一次遍历遇到奇数的先放到数组中,第二次遍历遇到偶数的放到数组中


方法 2:头尾指针 , 头指针找偶数,尾指针找奇数,找到之后,二者交换




然后这里是奇数在前偶数在后 &&相对顺序不变的情况:


利用插入排序的思想:



k 前面的元素不需要再后移了,所以挪动的元素区间是(k,i],把前面的挪到后面去,从后往前挪


a[i]&1 == 0 ->偶数


a[i]&1 == 1 ->奇数


class Solution {public:    void reOrderArray(vector<int> &array) {        int k = 0;//标志应该存放奇数的位置        //遍历数组,        //i位置遇到奇数:用临时遍历tmp保存当前位置的值        //就把[k,i-1)的元素往后移动,然后把tmp放到k位置下        //然后k++标志下一个应该存放奇数的位置        for(int i = 0;i<array.size();i++)        {            if(array[i] & 1)            {                //此时i位置为奇数,即i-1下标的元素为偶数                int tmp = array[i];//先保存当前位置的奇数                int j = i;                //把(k,i-1]的元素往后移动                //k位置应该是我们放奇数的位置,所以该位置不需要往后移动                for(int j = i;j>k;j--)                {                    array[j] = array[j-1];                }                array[k++] = tmp;            }        }    }};
复制代码



数组出现超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为 9 的数{1,2,3,2,2,2,5,4,2}.由于数字 2 在数组中出现了 5 次,超过数组长度的一半,因此输出 2.如果不存在则输出 0.


https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&tqId=11181&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking


因为有可能并不存在出现次数超过一半的数字,所以我们最后找到之后还需要再次遍历数组判断是否符合要求


方法 1:定义 map <数字,次数>的映射关系,最后统计每个数字出现的次数


class Solution {public:    int MoreThanHalfNum_Solution(vector<int> numbers) {        unordered_map<int,int> map;        int half = numbers.size()/2;        for(int i = 0;i<numbers.size();i++)        {            auto it = map.find(numbers[i]);//在map中查找是否右numbers[i]            //如果有,则自增,没有,则在map中插入该元素,首次出现            if(it!=map.end())            {                map[numbers[i]]++;            }            else            {                map.insert(make_pair(numbers[i],1)) ;               }                        //判断该元素的出现次数是否超过一半            if(map[numbers[i]]>half)            {                return numbers[i];            }        }        //找不到        return -1;    }};
复制代码


方法 2:排序,出现次数最多的数字,一定在中间位置,然后再次遍历数组,检测中间出现的数字是否符合要求


class Solution {    public:    int MoreThanHalfNum_Solution(vector<int> numbers) {        sort(numbers.begin(),numbers.end());//对数组进行排序        int ans = numbers[numbers.size()/2];//中间位置        //判断是否符合条件        int sum  =0;        for(int i = 0;i<numbers.size();i++)        {            if(numbers[i] == ans)            {                sum++;            }        }        //出现次数一定要>numbers.size()/2  不可以等于,因为超过一半        if(sum>numbers.size()/2)        {            return ans;        }        //并没有超过一半,即不存在超过一半的数字        return 0;    }};
复制代码




方法 3:抵消的思想


目标条件:目标数据超过数组长度的一半.

那么对数组,我们同时去掉两个不同的数字,到最后剩下的一个数就是该数字.如果剩下两个,那么这两个也是一样的,就是结果),将数组遍历一遍统计一下数字出现次数进行最终判断.


class Solution {    public:    int MoreThanHalfNum_Solution(vector<int> numbers) {        int ans = 0;        int count = 0;//ans出现的次数        for(int i =0;i<numbers.size();i++)        {            if(count == 0)            {                ans = numbers[i];                count=1;//注意要把count置为1            }            else if(ans == numbers[i])            {                count++;            }            else            {                count--;            }        }        //判断是否符合条件        int sum  =0;        for(int i = 0;i<numbers.size();i++)        {            if(numbers[i] == ans)            {                sum++;            }        }        //出现次数一定要>numbers.size()/2  不可以等于,因为超过一半        if(sum>numbers.size()/2)        {            return ans;        }        //并没有超过一半,即不存在超过一半的数字        return 0;    }};
复制代码




发布于: 刚刚阅读数: 3
用户头像

芒果酱

关注

我们都在努力奔跑,我们都是追梦人! 2022-02-14 加入

个人宣言:功崇惟志,业广惟勤 个人简介: 0.在校大学生 1.CSDN:C/C++领域新星创作者 2.掘金LV3创作者 3.华为云开发者社区云享专家 4.阿里云开发者社区专家博主 5.InfoQ创作者

评论

发布
暂无评论
【算法】剑指offer-调整数组顺序&&数组出现超过一半的数字_c++_芒果酱_InfoQ写作社区