华为机试:最长方连续方波信号

该博客介绍了一道编程题目,要求从输入的方波信号字符串中找到最长的完全连续交替方波,即01交替且不允许连续高位的信号。作者提到这个问题与LeetCode上的某些题目类似,但具有独特的条件。解决方案涉及到字符串操作,首先切割出所有可能的完整信号,然后检查这些信号是否为完全连续交替方波。通过遍历和比较,找出最长的符合条件的信号。提供的代码示例展示了如何实现这一过程。

题目来源

题目描述

输入一串方波信号,求取最长的完全连续交替方波信号,并将其输出,如果有相同长度的交替方波信号,输出任一即可,
方波信号高位用1标识,低位用0标识,如图:

说明:
1) 一个完整的信号一定以0开始然后以0结尾,即010是一个完整信号,但101,1010,0101不是
2)输入的一串方波信号是由一个或多个完整信号组成
3) 两个相邻信号之间可能有0个或多个低位,如0110010,011000010

4) 同一个信号中可以有连续的高位,如01110101011110001010,前14位是一个具有连续高位的信号

5) 完全连续交替方波是指10交替,如01010是完全连续交替方波,0110不是

输入描述:
输入信号字符串(长度>=3且<=1024):

0010101010110000101000010
注:输入总是合法的,不用考虑异常情况
输出描述:
输出最长的完全连续交替方波信号串:

01010
若不存在完全连续交替方波信号串,输出 -1

示例1
输入
00101010101100001010010
输出
01010
备注:
输入信号串中有三个信号:0 010101010110(第一个信号段) 00 01010(第二个信号段) 010(第三个信号段)

第一个信号虽然有交替的方波信号段,但出现了11部分的连续高位,不算完全连续交替方波,
在剩下的连续方波信号串中01010最长

题目解析

这道题让我想起了leetcode:978. 最长湍流子数组的长度。但是实际上是完全不同的,它要求信号必须以0开始&&必须以0结尾,而且中间是0和1交替。

也就是说,题目中给出了两个定义:

  • 完整信号:由01交替,我们称0是波谷,1是波峰,则 两头必须是波谷中间没有连续的波谷,但可以有连续的波峰,如 0111010110 。
  • 完全连续方波信号:由01交替,且 两头必须是波谷,中间必须是波峰波谷交错,不允许有连续的波峰,如 010101010 是OK的,但 0110 是不行的。

要求求出最长的连续方波信号

我第一反应是想用动态规划来做的,但是动态规划只会计算部分信号。

这道题的意思其实是考察字符串操作,让你先把完整信号切割出来,然后在判断是不是完全连续方波信号

#include <utility>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <functional>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <random>
#include <ctime>
#include <iterator>

using namespace std;

class Solution{
     // 0101010100
     // 功能: 以str[i]作为起始,什么时候信号结束
     // 什么时候信号结束:遇到两个00时,或者到达了字符串末尾
     // 一定会结束,不用担心找不到结束
     std::string finCompleteSignal(std::string str, int start){
         int pos = str.find("00", start);
         return pos == -1 ? str.substr(start) : str.substr(start, pos - start + 1);
     }

     // 验证是否是连续交替方波
    bool validXYXSignal(std::string &str){
        return str.find("11") == -1;
     }

public:
    std::string maxXYXSignal(std::string str){
         int i = 0;
         // 先将信号切割好
         std::vector<std::string> signalVec;
         while (i + 2 < str.size()){
             if(str[i] == '0' && str[i + 1] == '1'){
                 auto signal = finCompleteSignal(str, i);
                 signalVec.push_back(signal);
                 i = i +  (int)signal.size();
             }else{
                 i++;
             }
         }

         // 开始验证
         std::string ans;
         for(auto std : signalVec){
             if(validXYXSignal(std)){
                 ans = std.size() > ans.size() ? std : ans;
             }
         }

        return ans;
     }
};



int main(){
    std::string str =  "00101010101100001010010";

    Solution a;
    auto ans = a.maxXYXSignal(str);
    std::cout << (ans.empty() ? "-1" : ans) <<"\n";
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值