剑指Offer刷题记录_Day22

数学(simple)

Q1 数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

  • 思路一:哈希表,遍历,存储每个数出现的次数。

  • 思路二:排序,所求数一定位于中位数的位置

class Solution {
public:
    int majorityElement(vector<int>& nums) {

        int len = nums.size();
        if(len < 3) return nums[0];

        sort(nums.begin(),nums.end());

        return nums[len/2]; 

    }
};
  • 思路三:摩尔投票法。假设x为众数(本题中众数定义为一半以上),遍历数组,若该元素 == x,则众数x的权重w+1;若不相等,则w-1; 当 w == 0时,说明x已经不能作为众数,此时下一个元素成为x(众数候选),依次遍历完数组。x 最终一定为 众数。
class Solution {
public:
    int majorityElement(vector<int>& nums) {

        int x = 0 , w = 0;
        for(auto num : nums)
        {
            if(w == 0) {
                 x = num;
                 w++;}
            else {
                if(x == num) w++;
                else w--;}           }
        } 
        return x;
    }
};

Q2 构建乘积数组

给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。

解题思路:用数组b [ i ] 从左往右遍历递推记录前 i-1 个的乘积 。再从右往左遍历利用b[ i ] 和 从后往前递推的乘积 产生题目所需值。

class Solution {
public:
    vector<int> constructArr(vector<int>& a) {

        int len = a.size();
          
        if(len == 0) return {};
        vector<int> b(len,1);

        int tmp = 1;
        int b[0] = 1;
        
        for(int i = 1;i < len; i++)
          {
              tmp *= a[i-1];
              b[i] = tmp;
          }
        tmp = a[len-1];
        for(int i = len-2;i >= 0;i--)
        {
            b[i] = b[i] * tmp;
            tmp *= b[i];
        }
          
        return b;


    }
};
上一篇:exchange发邮件


下一篇:设计模式-第十章-观察者模式(c++)