carloscn / structstudy

Leetcode daily trainning by using C/C++/RUST programming.
4 stars 1 forks source link

leetcode942:增减字符串匹配(di-string-match) #171

Open carloscn opened 1 year ago

carloscn commented 1 year ago

问题描述

由范围 [0,n] 内所有整数组成的 n + 1 个整数的排列序列可以表示为长度为 n 的字符串 s ,其中:

如果 perm[i] < perm[i + 1] ,那么 s[i] == 'I'  如果 perm[i] > perm[i + 1] ,那么 s[i] == 'D'  给定一个字符串 s ,重构排列 perm 并返回它。如果有多个有效排列perm,则返回其中 任何一个 。

 

示例 1:

输入:s = "IDID" 输出:[0,4,1,3,2] 示例 2:

输入:s = "III" 输出:[0,1,2,3] 示例 3:

输入:s = "DDI" 输出:[3,2,0,1]  

提示:

1 <= s.length <= 105 s 只包含字符 "I" 或 "D"

来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/di-string-match

carloscn commented 1 year ago

问题分析

题目比较难理解,其实意思就是根据输入字符串生成数组,字符串只有I和D,遇到I字符则生成一个相对递增的数,如果遇到D则生成一个相对递减的数。数字在 0 - n 范围内挑选,且只能用一次。

这里我标记贪心算法,有点局部最优的意思:

pub fn di_string_match(s: String) -> Vec<i32>
{
    let mut ret:Vec<i32> = vec![];
    let mut range:Vec<i32> = vec![];
    let s_v:Vec<char> = s.chars().into_iter().collect();

    if s.len() < 1 {
        return ret;
    }

    for i in 0..(s.len() + 1) {
        range.push(i as i32);
    }

    for e in &s_v {
        if 'I' == *e {
            ret.push(*range.get(0).unwrap());
            range.remove(0);
        } else if 'D' == *e {
            ret.push(range.pop().unwrap());
        }
    }
    ret.push(range[0]);

    return ret;
}
carloscn commented 1 year ago

code

https://github.com/carloscn/structstudy/commit/c92518a06703e5e3cd03e5cdb3163b692efea9ef https://review.gerrithub.io/c/carloscn/structstudy/+/551988