[经典面试题][搜狗]在一个字符串中寻找包含全部出现字符的最小字串

本文介绍了一种寻找字符串中包含所有指定字符最短子串的高效算法,通过统计字符频率和滑动窗口的方法,在O(n)时间内解决问题。

题目

一个字符串中含有n个字符,其中有m个不同的字符,n>>m,用最少的时间和空间找到包含所有这m个字符的最短的字串,不考虑特殊字符,只考虑字母数字即可。
例如:
abccbaddac, 返回:cbad
aabcadbbbcca,返回:bcad

思路

[算法系列之二十二]包含T全部元素的最小子窗口
本题目相比连接中所说的稍微简单一些,本题目不用考虑重复字符。

代码

    /*---------------------------------------------
    *   日期:2015-02-24
    *   作者:SJF0115
    *   题目: 包含全部出现字符的最小字串
    *   来源:搜狗
    *   博客:
    -----------------------------------------------*/
    #include <iostream>
    #include <climits>
    using namespace std;

    string MinWindow(string S){
        int slen = S.size();
        if(slen <= 0){
            return "";
        }//if
        int minWinStart,minWinEnd;
        int minWinLen = INT_MAX;
        // 统计不同字符个数
        int m = 0;
        int needFind[256] = {0};
        for(int i = 0;i < slen;++i){
            needFind[S[i]] = 1;
        }//for
        for(int i = 0;i < 256;++i){
            if(needFind[i] == 1){
                ++m;
            }//if
        }//for

        int hasFound[256] = {0};
        int val;
        int count = 0;
        for(int start = 0,end = 0;end < slen;++end){
            val = S[end];
            ++hasFound[val];
            if(hasFound[val] <= 1){
                ++count;
            }//if
            // 找到一子串包含全部不同的字符
            if(count == m){
                int startEle = S[start];
                while(hasFound[startEle] > 1){
                    --hasFound[startEle];
                    ++start;
                    startEle = S[start];
                }//while

                int curWinLen = end - start + 1;
                if(minWinLen > curWinLen){
                    minWinLen = curWinLen;
                    minWinStart = start;
                    minWinEnd = end;
                }//if
            }//if
        }//for
        if(count != m){
            return "";
        }//if
        return S.substr(minWinStart,minWinEnd - minWinStart + 1);
    }

    int main() {
        string S("aabcadbbbcca");
        cout<<MinWindow(S)<<endl;
    }

引用:

[算法系列之二十二]包含T全部元素的最小子窗口

相似题目:

[LeetCode]76.Minimum Window Substring

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
<think>好的,用户想了解虚幻引擎中材质的使用教程或效果实现。首先,我需要整理UE材质系统的基础知识。材质编辑器是核心工具,用户需要知道如何创建和编辑材质节点。然后,基础材质属性如基础颜色、金属感、高光、粗糙度、法线贴图等都是关键点,必须详细说明每个属性的作用和应用场景。 接下来,效果实现部分,用户可能对常见材质效果感兴趣,比如透明材质、动态效果、视差遮挡和发光材质。需要分步骤解释如何实现这些效果,并给出节点连接的示例。比如透明材质需要调整混合模式和不透明度,动态效果可能需要使用Time节点驱动纹理坐标变化。 引用部分要自然地融入回答中。根据提供的引用,UE5的物理系统相关部分可能不太直接相关,但材质与渲染紧密相关,可能需要提到材质如何影响物体外观,结合物理属性如金属感来增强真实感。引用中的教程和更新动态可以作为推荐用户进一步学习的资源。 用户可能还关心性能优化,比如材质复杂度和实例的使用。需要提醒用户注意材质复杂度对性能的影响,并建议使用材质实例化来提升效率。此外,参考社区动态和官方文档也是重要的,确保信息的时效性。 最后,生成的相关问题要围绕材质制作的深入技巧、性能优化、高级效果和与其他系统的结合。这些问题应引导用户进一步探索,覆盖他们可能感兴趣的后续主题。确保所有步骤都符合系统指令,正确使用LaTeX格式,回答结构清晰,分点明确,帮助用户逐步掌握材质制作的方法。</think>### 虚幻引擎(UE材质使用教程与效果实现 #### 一、材质系统基础 1. **材质编辑器** - 创建材质:在内容浏览器右键选择`材质`,双击打开材质编辑器界面[^3] - 节点构成:基础颜色、金属感、高光、粗糙度、法线贴图等核心输入项 - 常用快捷键:按住`1`+左键创建标量值,`3`创建三维向量(RGB颜色) 2. **基础材质属性** $$ \text{最终效果} = f(\text{BaseColor}, \text{Metallic}, \text{Specular}, \text{Roughness}) $$ - `BaseColor`:控制表面基础颜色(支持纹理采样) - `Metallic`:0-1范围,0为非金属,1为全金属 - `Roughness`:表面光滑度,0为镜面反射,1为完全漫反射 #### 二、常见效果实现 1. **透明材质** ```cpp // 材质设置步骤: 1. 混合模式改为Translucent 2. 添加Opacity节点 3. 连接透明度纹理或标量值 ``` ![透明材质节点示例](https://docs.unrealengine.com/Static/EN_Tutorials/Materials/MatIntro/Image_04.png)(需替换为实际链接) 2. **动态材质效果** - 使用`Time`节点驱动纹理坐标: $$ UV = TexCoord + Time \times Speed $$ - 通过材质参数集合实现运行时动态修改参数[^2] 3. **视差遮挡贴图** ```python # 节点连接逻辑: HeightTexture -> ParallaxOcclusionMapping -> 影响最终法线与光照计算 ``` #### 三、高级技巧 1. **材质函数封装** - 将重复使用的节点网络封装为函数(如环境光遮蔽计算) - 通过函数输入输出接口提升复用性 2. **材质实例化** - 创建父材质后派生实例,动态修改参数值 - 降低Draw Call,提升渲染效率[^1] #### 四、性能优化建议 1. 使用`Stat GPU`命令分析材质复杂度 2. 纹理尺寸不超过2048x2048(移动端建议1024x1024) 3. 避免过度使用复杂数学运算节点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值