【算法日记】找出最长神奇数列 找出整数数组中占比超过1/N的元素

题目描述 题号:97

问题描述

小明是一个中学生,今天他刚刚学习了数列。他在纸上写了一个长度为 n 的正整数序列, a 0 , a 1 , … , a n − 1 a_0,a_1,\ldots,a_{n-1} a0,a1,,an1。这个数列里面只有 1 和 0,我们将 1 和 0 没有重复跟随并且至少由 3 个数组成的数列的数列称之为「神奇数列」。比如 10101 是一个神奇数列,1011 不是一个神奇数列。他想知道这个序列里面最长的「神奇数列」是哪个,你可以帮帮他吗?

输入格式
  • 一行连续的数 s,只有 01
输出格式
  • 一行数
输入样例

0101011101

输出样例

010101

数据范围
  • 1 < s . l e n g t h ≤ 5 × 1 0 4 1 < s.length \leq 5 \times 10^4 1<s.length5×104

思路

这道题是找符合题目要求的子串,我们可以模拟寻找过程。使用vector来装入每个子串,然后找出最长的子串既是答案。通过遍历主串来寻找子串,通过模拟规则,下一个数和上一个数相反,我们可以写一个转变的函数来实现,然后通过if来判断下一个数是否符合,符合就push_back到子串,否则就到头了,这时我们把已经push完成的子串push到子串数组中,然后使得外循环的i = 内循环的j以免不必要的时间开销。具体实现,如下。

源码

C++

#include <iostream>
#include <string>
#include <vector>

char reverseFlag(char flag) { return flag == '1'? '0' : '1'; }

std::string solution(const std::string& inp) {
    std::vector<std::vector<char>> subStrings;
    for (int i = 0; i < inp.size()-1; i++) {
        std::vector<char> subStr;
        subStr.push_back(inp[i]);
        for (int j = i+1; j < inp.size(); j++) {
            if (reverseFlag(subStr[j-1]) == inp[j]) {
                subStr.push_back(inp[j]);
            } else {
                subStrings.push_back(subStr);
                i = j;
                break;
            }
        }
    }
    // 找出最长项
    int max = 0, max_Index = 0;
    for (int i = 0; i < subStrings.size(); i++) {
        if (subStrings[i].size() > max) {
            max = subStrings[i].size();
            max_Index = i;
        }
    }
    // 无符合要求的子串
    if (max <= 2) return "";
    // 把最长项装入字符串
    std::string res;
    for (char i : subStrings[max_Index]) {
        res.push_back(i);
    }

    return res;
}

int main() {
    // Add your test cases here
    
    std::cout << (solution("0101011101") == "010101") << std::endl;
    return 0;
}

题目描述 题号:96

问题描述
  • 给定一个长度为n的整型数组,已知其中一个数字的出现次数超过数组长度的一半,找出这个元素
输入格式
  • 一个长度为n的数组,其中某个元素的出现次数大于n/2
输出格式
  • 一个整数
输入样例
  • [1,3,8,2,3,1,3,3,3]
输出样例
  • 3
数据范围
  • 任意长度为n整数数组,其中某个元素的出现次数大于n/2

思路

使用容器map,键为出现的数字,值为该数字出现的次数,通过一次遍历数组,我们得到了这个数组内数字种类及其出现次数,通过遍历map容器,找出大于N的键后返回,否则返回-1

源码

C++

#include <iostream>
#include <vector>
#include <map>

using namespace std;

int solution(vector<int> array) {
    // Edit your code here
    int N = array.size() / 2;
    std::map<int, int> mp;
    for (int i : array) {
        if (mp.find(i) != mp.end()) {
            mp.at(i) = mp.at(i) + 1;
        } else {
            mp.insert(pair(i, 0));
        }
    }
    for (const auto i : mp) {
        if (i.second >= N) {
            return i.first;
        }
    }
    // 无结果
    return -1;
}

int main() {
    // Add your test cases here
    
    cout << (solution({1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3) << endl;
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值