数组做过的题目记录

1.数组中占比超过一半的元素称之为主要元素。给定一个整数数组,找到它的主要元素。若没有,返回-1

第一种方法,也是我第一次实现的方法:先对数组进行排序,然后从数组头开始循环判断,步进值为数组的一半,如果当前和步进值处的数组元素是相等的,说明这个就是主要元素。

另外还有一些特殊情况,比如数组元素为0、为1、为2的时候也是易于判断的。

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

        int len = nums.size();
        if(len == 0)
            return -1;
        else if(len == 1)
            return nums[0];
        else if(len ==2)
            return nums[0]==nums[1]? nums[0] : -1;
        sort(nums.begin(),nums.end());//使用sort方法进行从小到大的排序
        //对排好序的进行判断,步进为size一半,如果还想等,说明是主要元素
        for(int i=0;(i+len/2)<len;i++)
        {
            if(nums[i]==nums[i+len/2])
                return nums[i];
        }
        return -1;

    }
};

 2.数组中第K个最大元素

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

例如:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
class Solution
{
public:
    int findKthLargest(vector<int> &nums, int k)
    {
        int result = 0;
        int numsSize = int(nums.size());//得到数组长度
        if (numsSize == 0 || k > numsSize)
        {
            return 0;
        }
        //寻找第kMIN小的数
        int kMin = numsSize - k + 1;//寻找第k个最大的数就是寻找第kMin个最小的数
        result = select(nums, 0, numsSize - 1, kMin);
        return result;
    }

    int select(vector<int> &nums, int left, int right, int target)
    {
        if (left == right)
        {
            return nums[left];
        }
        int cut = partition(nums, left, right);
        //当前第currentResult小的元素
        int currentResult = cut - left + 1;
        if (target == currentResult)
        {
            return nums[cut];
        }
        else if (target < currentResult)//如果比当前的基准值小,就在左边的部分里找
        {
            return select(nums, left, cut - 1, target);
        }
        else
        {
            //寻找接下来第target - currentResult小的数
            return select(nums, cut + 1, right, target - currentResult);
        }
        return 0;
    }

    int partition(vector<int> &nums, int left, int right)
    {
        int cut = nums[right];//算法导论里取的是这个数用来当做基准值
        //i指向最左边的数,j指向下一个判断的数
        int i = left;
        for (int j = left; j < right; j++)
        {
            if (nums[j] <= cut)
            {
                exchange(nums[i], nums[j]);
                i++;
            }
        }
        exchange(nums[i], nums[right]);//将基准值归位到第i个数
        return i;
    }

    void exchange(int &a, int &b)
    {
        int tmpInt = a;
        a = b;
        b = tmpInt;
        return;
    }
};

3.数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

class Solution {
public:
    int findRepeatNumber(vector<int>& nums) {
        //首先可以判断特殊情况,但是题目已经给定了n>=2
        //采用哈希表的思路解决这个问题。因为所有数字都在0~n-1之间,因此可以用数组的下标作为哈希表的key,
        //元素值作为哈希表的value,将每个key和value对应,比如key=0时存放的就是0,
        auto length = nums.size();
        for(int i=0;i<length;i++)
        {
            while(nums.at(i)!=i)
            {
                if(nums.at(i) == nums.at(nums.at(i)))
                    return nums.at(i);
                int temp = nums.at(i);
                nums.at(i) = nums.at(temp);
                nums.at(temp) = temp;
            }
        }
        return NULL;
        

    }
};

4.数组的度

 

class Solution {
public:
    int findShortestSubArray(vector<int>& nums) {
        unordered_map<int,int> left,right,counter;
        int degree = 0;
        for (int i = 0; i < nums.size(); i++) {
            if (!left.count(nums[i])) {
                left[nums[i]] = i;
            }
            right[nums[i]] = i;
            counter[nums[i]]++;
            degree = max(degree, counter[nums[i]]);
        }
        int length = nums.size();
        for (auto& it : counter) { //对于counter里的每一个pair
            if (it.second == degree) {
                length = min(length, right[it.first] - left[it.first] + 1);
            }
        }
        return length;
    }
};

 



posted @ 2020-12-04 18:51  不妨不妨,来日方长  阅读(39)  评论(0编辑  收藏  举报