字符串中的匹配之递归

字符串的括号匹配是一个很常见的问题。用栈这种后进先出的结构是非常适合的。此外,字符串中的回文以及衍生的各种问题也是字符串处理中非常常见的。

今天再说一下这类相似的问题,如何用递归来转化成子结构来求解。

先放一条LeetCode例题: 680. Valid Palindrome II

Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome.
Example 1:
Input: "aba"
Output: True

Example 2:
Input: "abca"
Output: True

题目的意思是:至多删除一个字母判断是否能删成回文。字符串长度是50000.

显然不能O(n^2)暴力。然后我们分析一下,其实我们只要能找出这个有问题的字母的位置在哪里就好了,然后删掉它就行了。可以通过判断是哪个字母的个数是奇数来做吗?不能,因为判断出来是什么字母,但当这个字母有很多时我们还是不知道删掉其中的哪一个。

所以就用到所说的递归:

两个指针从左边和右分别扫,扫到不匹配的时候就递归,分别删掉左边或右边的这个字母来判断新串是不是回文。

注意的是,已经判断回文的部分就不需要递归了,否则就起不到递归的作用了。时间复杂度: O(n)

AC代码:

class Solution {
public:
    bool isHuiwen(string& s,int l,int r){
        while (l < r){
            if (s[l] != s[r])
                return false;
            l++;
            r--;
        }
        return true;
    }
    bool validPalindrome(string s) {
        bool res;
        int l, r;
        l = 0;
        r = s.size()-1;
        while (l < r){
            if (s[l] != s[r])
                return isHuiwen(s, l+1, r) || isHuiwen(s, l, r-1);
            l++;
            r--;
        }
        return isHuiwen(s, 0, s.size()-1);
    }
};

再放一道LeetCode例题: 678. Valid Parenthesis String

Given a string containing only three types of characters: ‘(‘, ‘)‘ and ‘*‘, write a function to check whether this string is valid. We define the validity of a string by these rules:

  1. Any left parenthesis ‘(‘ must have a corresponding right parenthesis ‘)‘.
  2. Any right parenthesis ‘)‘ must have a corresponding left parenthesis ‘(‘.
  3. Left parenthesis ‘(‘ must go before the corresponding right parenthesis ‘)‘.
  4. ‘*‘ could be treated as a single right parenthesis ‘)‘ or a single left parenthesis ‘(‘ or an empty string.
  5. An empty string is also valid.

Example 1:
Input: "()"
Output: True

Example 2:
Input: "(*)"
Output: True

Example 3:
Input: "(*))"
Output: True

题意就是判断是否括号匹配,其中*可任意充当(或者)或者空白。

如果是没有*,那么做法很显然:从左到右统计(和)的个数。如果)的个数>(的个数就不行。判断到结尾的时候,如果两者个数相等就可以。

现在引入了*这个百搭,我们同样可以用递归来做:

如果遇到一个*,就分别把它视为左括号或者右括号或者空白来对后面的子串递归。

AC代码:

class Solution2 {
public:
    int lll;

    bool check(string& s,int start,int lcnt,int rcnt){
        int l, r;
        l = lcnt;
        r = rcnt;
        for (int i = start; i < lll; ++i){
            if (s[i] == ‘(‘)
                l++;
            if (s[i] == ‘)‘)
                r++;
            if (r > l)
                return false;
            if (s[i]==‘*‘){
                return check(s, i+1, l+1, r) ||
                       check(s, i+1, l, r+1) ||
                        check(s, i+1, l, r);
            }
        }
        return l == r;
    }

    bool checkValidString(string s) {
        lll = s.size();
        return check(s, 0, 0, 0);
    }
};

另外,这道题再说一个很巧妙的做法,思路来源于讨论区的高票帖。

low代表左括号可能出现的下界,high代表左括号可能出现的上界。

  • 当遇到一个(时,low++,high++;
  • 当遇到一个)时,low--,high--;
  • 当遇到一个*时,low--,high++; (即我们既可以把*看成(也可以看成)
  • 注意的是,下界一旦小于0直接返回false代表右括号太多了, 但是上界我们得人为保证其值>=0,因为*可以被视作空白或右括号(例如"(**")。但是最后结束的时候必须保证上界为0,如果最后上界不为0就是左括号太多了。

另附AC代码:

class Solution {
public:
    bool checkValidString(string s) {
        int lower = 0, upper = 0;
        for (char c : s) {
            if (c==‘(‘) {
                lower++;
                upper++;
            } else if (c==‘)‘) {
                lower--;
                upper--;
            } else { // * encountered
                lower--;
                upper++;
            }
            lower = max(lower, 0);
            if (upper<0) // unmatched ‘)‘ found in the middle of string
                return false;
        }
        return lower==0;
    }
};

*:first-child {
margin-top: 0 !important;
}

.markdown-body>*:last-child {
margin-bottom: 0 !important;
}

.markdown-body .anchor {
position: absolute;
top: 0;
bottom: 0;
left: 0;
display: block;
padding-right: 6px;
padding-left: 30px;
margin-left: -30px;
}

.markdown-body .anchor:focus {
outline: none;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
position: relative;
margin-top: 1em;
margin-bottom: 16px;
font-weight: bold;
line-height: 1.4;
}

.markdown-body h1 .octicon-link,
.markdown-body h2 .octicon-link,
.markdown-body h3 .octicon-link,
.markdown-body h4 .octicon-link,
.markdown-body h5 .octicon-link,
.markdown-body h6 .octicon-link {
display: none;
color: #000;
vertical-align: middle;
}

.markdown-body h1:hover .anchor,
.markdown-body h2:hover .anchor,
.markdown-body h3:hover .anchor,
.markdown-body h4:hover .anchor,
.markdown-body h5:hover .anchor,
.markdown-body h6:hover .anchor {
height: 1em;
padding-left: 8px;
margin-left: -30px;
line-height: 1;
text-decoration: none;
}

.markdown-body h1:hover .anchor .octicon-link,
.markdown-body h2:hover .anchor .octicon-link,
.markdown-body h3:hover .anchor .octicon-link,
.markdown-body h4:hover .anchor .octicon-link,
.markdown-body h5:hover .anchor .octicon-link,
.markdown-body h6:hover .anchor .octicon-link {
display: inline-block;
}

.markdown-body h1 {
padding-bottom: 0.3em;
font-size: 2.25em;
line-height: 1.2;
border-bottom: 1px solid #eee;
}

.markdown-body h2 {
padding-bottom: 0.3em;
font-size: 1.75em;
line-height: 1.225;
border-bottom: 1px solid #eee;
}

.markdown-body h3 {
font-size: 1.5em;
line-height: 1.43;
}

.markdown-body h4 {
font-size: 1.25em;
}

.markdown-body h5 {
font-size: 1em;
}

.markdown-body h6 {
font-size: 1em;
color: #777;
}

.markdown-body p,
.markdown-body blockquote,
.markdown-body ul,
.markdown-body ol,
.markdown-body dl,
.markdown-body table,
.markdown-body pre {
margin-top: 0;
margin-bottom: 16px;
}

.markdown-body hr {
height: 4px;
padding: 0;
margin: 16px 0;
background-color: #e7e7e7;
border: 0 none;
}

.markdown-body ul,
.markdown-body ol {
padding-left: 2em;
}

.markdown-body ul ul,
.markdown-body ul ol,
.markdown-body ol ol,
.markdown-body ol ul {
margin-top: 0;
margin-bottom: 0;
}

.markdown-body li>p {
margin-top: 16px;
}

.markdown-body dl {
padding: 0;
}

.markdown-body dl dt {
padding: 0;
margin-top: 16px;
font-size: 1em;
font-style: italic;
font-weight: bold;
}

.markdown-body dl dd {
padding: 0 16px;
margin-bottom: 16px;
}

.markdown-body blockquote {
padding: 0 15px;
color: #777;
border-left: 4px solid #ddd;
}

.markdown-body blockquote>:first-child {
margin-top: 0;
}

.markdown-body blockquote>:last-child {
margin-bottom: 0;
}

.markdown-body table {
display: block;
width: 100%;
overflow: auto;
word-break: normal;
word-break: keep-all;
}

.markdown-body table th {
font-weight: bold;
}

.markdown-body table th,
.markdown-body table td {
padding: 6px 13px;
border: 1px solid #ddd;
}

.markdown-body table tr {
background-color: #fff;
border-top: 1px solid #ccc;
}

.markdown-body table tr:nth-child(2n) {
background-color: #f8f8f8;
}

.markdown-body img {
max-width: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

.markdown-body code {
padding: 0;
padding-top: 0.2em;
padding-bottom: 0.2em;
margin: 0;
font-size: 85%;
background-color: rgba(0,0,0,0.04);
border-radius: 3px;
}

.markdown-body code:before,
.markdown-body code:after {
letter-spacing: -0.2em;
content: "\00a0";
}

.markdown-body pre>code {
padding: 0;
margin: 0;
font-size: 100%;
word-break: normal;
white-space: pre;
background: transparent;
border: 0;
}

.markdown-body .highlight {
margin-bottom: 16px;
}

.markdown-body .highlight pre,
.markdown-body pre {
padding: 16px;
overflow: auto;
font-size: 85%;
line-height: 1.45;
background-color: #f7f7f7;
border-radius: 3px;
}

.markdown-body .highlight pre {
margin-bottom: 0;
word-break: normal;
}

.markdown-body pre {
word-wrap: normal;
}

.markdown-body pre code {
display: inline;
max-width: initial;
padding: 0;
margin: 0;
overflow: initial;
line-height: inherit;
word-wrap: normal;
background-color: transparent;
border: 0;
}

.markdown-body pre code:before,
.markdown-body pre code:after {
content: normal;
}

.markdown-body .highlight {
background: #fff;
}

.markdown-body .highlight .mf,
.markdown-body .highlight .mh,
.markdown-body .highlight .mi,
.markdown-body .highlight .mo,
.markdown-body .highlight .il,
.markdown-body .highlight .m {
color: #945277;
}

.markdown-body .highlight .s,
.markdown-body .highlight .sb,
.markdown-body .highlight .sc,
.markdown-body .highlight .sd,
.markdown-body .highlight .s2,
.markdown-body .highlight .se,
.markdown-body .highlight .sh,
.markdown-body .highlight .si,
.markdown-body .highlight .sx,
.markdown-body .highlight .s1 {
color: #df5000;
}

.markdown-body .highlight .kc,
.markdown-body .highlight .kd,
.markdown-body .highlight .kn,
.markdown-body .highlight .kp,
.markdown-body .highlight .kr,
.markdown-body .highlight .kt,
.markdown-body .highlight .k,
.markdown-body .highlight .o {
font-weight: bold;
}

.markdown-body .highlight .kt {
color: #458;
}

.markdown-body .highlight .c,
.markdown-body .highlight .cm,
.markdown-body .highlight .c1 {
color: #998;
font-style: italic;
}

.markdown-body .highlight .cp,
.markdown-body .highlight .cs {
color: #999;
font-weight: bold;
}

.markdown-body .highlight .cs {
font-style: italic;
}

.markdown-body .highlight .n {
color: #333;
}

.markdown-body .highlight .na,
.markdown-body .highlight .nv,
.markdown-body .highlight .vc,
.markdown-body .highlight .vg,
.markdown-body .highlight .vi {
color: #008080;
}

.markdown-body .highlight .nb {
color: #0086B3;
}

.markdown-body .highlight .nc {
color: #458;
font-weight: bold;
}

.markdown-body .highlight .no {
color: #094e99;
}

.markdown-body .highlight .ni {
color: #800080;
}

.markdown-body .highlight .ne {
color: #990000;
font-weight: bold;
}

.markdown-body .highlight .nf {
color: #945277;
font-weight: bold;
}

.markdown-body .highlight .nn {
color: #555;
}

.markdown-body .highlight .nt {
color: #000080;
}

.markdown-body .highlight .err {
color: #a61717;
background-color: #e3d2d2;
}

.markdown-body .highlight .gd {
color: #000;
background-color: #fdd;
}

.markdown-body .highlight .gd .x {
color: #000;
background-color: #faa;
}

.markdown-body .highlight .ge {
font-style: italic;
}

.markdown-body .highlight .gr {
color: #aa0000;
}

.markdown-body .highlight .gh {
color: #999;
}

.markdown-body .highlight .gi {
color: #000;
background-color: #dfd;
}

.markdown-body .highlight .gi .x {
color: #000;
background-color: #afa;
}

.markdown-body .highlight .go {
color: #888;
}

.markdown-body .highlight .gp {
color: #555;
}

.markdown-body .highlight .gs {
font-weight: bold;
}

.markdown-body .highlight .gu {
color: #800080;
font-weight: bold;
}

.markdown-body .highlight .gt {
color: #aa0000;
}

.markdown-body .highlight .ow {
font-weight: bold;
}

.markdown-body .highlight .w {
color: #bbb;
}

.markdown-body .highlight .sr {
color: #017936;
}

.markdown-body .highlight .ss {
color: #8b467f;
}

.markdown-body .highlight .bp {
color: #999;
}

.markdown-body .highlight .gc {
color: #999;
background-color: #EAF2F5;
}

.markdown-body .octicon {
font: normal normal 16px octicons-anchor;
line-height: 1;
display: inline-block;
text-decoration: none;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}

.markdown-body .octicon-link:before {
content: ‘\f05c‘;
}

.markdown-body .task-list-item {
list-style-type: none;
}

.markdown-body .task-list-item+.task-list-item {
margin-top: 3px;
}

.markdown-body .task-list-item input {
float: left;
margin: 0.3em 0 0.25em -1.6em;
vertical-align: middle;
}

/*

github.com style (c) Vasily Polovnyov

*/

.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
background: #f8f8f8;
-webkit-text-size-adjust: none;
}

.hljs-comment,
.diff .hljs-header {
color: #998;
font-style: italic;
}

.hljs-keyword,
.css .rule .hljs-keyword,
.hljs-winutils,
.nginx .hljs-title,
.hljs-subst,
.hljs-request,
.hljs-status {
color: #333;
font-weight: bold;
}

.hljs-number,
.hljs-hexcolor,
.ruby .hljs-constant {
color: #008080;
}

.hljs-string,
.hljs-tag .hljs-value,
.hljs-doctag,
.tex .hljs-formula {
color: #d14;
}

.hljs-title,
.hljs-id,
.scss .hljs-preprocessor {
color: #900;
font-weight: bold;
}

.hljs-list .hljs-keyword,
.hljs-subst {
font-weight: normal;
}

.hljs-class .hljs-title,
.hljs-type,
.vhdl .hljs-literal,
.tex .hljs-command {
color: #458;
font-weight: bold;
}

.hljs-tag,
.hljs-tag .hljs-title,
.hljs-rule .hljs-property,
.django .hljs-tag .hljs-keyword {
color: #000080;
font-weight: normal;
}

.hljs-attribute,
.hljs-variable,
.lisp .hljs-body,
.hljs-name {
color: #008080;
}

.hljs-regexp {
color: #009926;
}

.hljs-symbol,
.ruby .hljs-symbol .hljs-string,
.lisp .hljs-keyword,
.clojure .hljs-keyword,
.scheme .hljs-keyword,
.tex .hljs-special,
.hljs-prompt {
color: #990073;
}

.hljs-built_in {
color: #0086b3;
}

.hljs-preprocessor,
.hljs-pragma,
.hljs-pi,
.hljs-doctype,
.hljs-shebang,
.hljs-cdata {
color: #999;
font-weight: bold;
}

.hljs-deletion {
background: #fdd;
}

.hljs-addition {
background: #dfd;
}

.diff .hljs-change {
background: #0086b3;
}

.hljs-chunk {
color: #aaa;
}
-->

时间: 2024-12-20 09:20:38

字符串中的匹配之递归的相关文章

SAP ABAP编程 在string类型A字符串中查询匹配string类型B字符串

如题,在string类型A字符串中查询匹配string类型B字符串,方法如下: DATA: a TYPE string VALUE 'ABCDEFGHIJKLNM', b TYPE string VALUE 'EFGHIJ', c TYPE string . DATA: off  TYPE i VALUE 0,   "从自己个字符开始查找 moff TYPE i, mlen TYPE i. FIND b IN SECTION OFFSET off OF a MATCH OFFSET moff &

js 替换字符串中所有匹配的字符

var str = 'abcadeacf'; var str1 = str.replace('a', 'o'); alert(str1); // 打印结果: obcadeacf var str2 = str.replace(/a/g, 'o'); alert(str2); //打印结果: obcodeocf, 注意: 此处replace的第一个参数为正则表达式,/g是全文匹配标识. 原文地址:https://www.cnblogs.com/wind-wang/p/9648146.html

40 python 正则表达式 match方法匹配字符串 使用search函数在一个字符串中查找子字

第一课: 使用match方法匹配字符串 # 正则表达式:使用match方法匹配字符串 ''' 正则表达式:是用来处理文本的,将一组类似的字符串进行抽象,形成的文本模式字符串 windows dir *.txt file1.txt file2.txt abc.txt test.doc a-file1.txt-b linux/mac ls 主要是学会正则表达式的5方面的方法 1. match:检测字符串是否匹配正则表达式 2. search:在一个长的字符串中搜索匹配正则表达式的子字符串 3. fi

Python字符串处理:过滤字符串中的英文与符号,保留汉字

使用Python 的re模块,re模块提供了re.sub用于替换字符串中的匹配项. 1 re.sub(pattern, repl, string, count=0) 参数说明: pattern:正则重的模式字符串 repl:被拿来替换的字符串 string:要被用于替换的原始字符串 count:模式匹配后替换的最大次数,省略则默认为0,表示替换所有的匹配 例如 import re str = "hello,world!!%[545]你好234世界..." str = re.sub(&q

【c语言】编写一个函数reverse_string(char * string)(递归实现) 实现:将参数字符串中的字符反向排列。

/*编写一个函数reverse_string(char * string)(递归实现) 实现:将参数字符串中的字符反向排列. 要求:不能使用C函数库中的字符串操作函数.*/ #include <stdio.h> #include <assert.h> void reverse_string(char const * string) { assert( string != NULL ); if( *string != '\0' ) { string++; reverse_string

将字符串s1中的任何与字符串s2中字符匹配的字符都删除

编写一个程序,将字符串s1中的任何与字符串s2中字符匹配的字符都删除. 函数原型:void my_squeeze(char s1[], char s2[]) #include <stdio.h> void my_squeeze(char s1[], char s2[]) { int i = 0; int j = 0; while (s2[j]) { while(s1[i]) { if (s2[j]==s1[i]) { while (s1[i+1]) { s1[i] = s1[i + 1]; i

递归方式解析出字符串中的@某人

<?php $userList = []; /** * 用递归的方式来查找字符串中的 @用户名 * 用法:@用户名之后需要加空格隔断,才能检测到 * @param $content */ function fetchAt($content) { global $userList; $afterAt = strstr($content, '@'); //@符号之后 if ($afterAt) { $username = strstr($afterAt, ' ', true); //用户名 if (

华为OJ:2199 判断输入字符串中的括号匹配

根据不同的括号有个计数器,在遍历时,当计数器小于0则返回false或者当遍历完后,计数器仍旧不为零,也返回false. import java.util.Scanner; public class bracketsMatch { public static void main(String args[]){ Scanner input=new Scanner(System.in); String s=input.nextLine(); int a=0; int b=0; int c=0; for

[Python正则表达式] 字符串中xml标签的匹配

现在有一个需求,比如给定如下数据: 2009-2-12 9:22:2 #### valentine s day 2011 #### sex is good for you #### Making love pleasures life genuinely good say researchers does healthy sex life boost mood growing evidence boosts physical increasing longevity reducing risk