• 1239. Maximum Length of a Concatenated String with Unique Characters


    问题:

    给定一组字符串数组,

    有这些字符串合并构成不存在重复字符的“集连字符串”

    求该集连字符串最大长度。

    Example 1:
    Input: arr = ["un","iq","ue"]
    Output: 4
    Explanation: All possible concatenations are "","un","iq","ue","uniq" and "ique".
    Maximum length is 4.
    
    Example 2:
    Input: arr = ["cha","r","act","ers"]
    Output: 6
    Explanation: Possible solutions are "chaers" and "acters".
    
    Example 3:
    Input: arr = ["abcdefghijklmnopqrstuvwxyz"]
    Output: 26
     
    Constraints:
    1 <= arr.length <= 16
    1 <= arr[i].length <= 26
    arr[i] contains only lower case English letters.
    

      

    解法:Backtracking(回溯算法)

    状态:选到当前位置pos的字符串后,所构成的集连字符串 字符统计结果 path

    选择:从当前位置pos到数组结束,所有字符串中,除去:包含目前位置选入统计结果path中已经包含字符的。本身存在重复字符的。

    退出递归条件:pos选到数组最后一位。

    定义字符统计结果 StrInfo结构体:

    struct StrInfo{
        int len;
        int aset[26];
    };

    aset[i]表示字符'a'+i 出现的次数,

    ⚠️  注意:

    1. 若出现次数>1的时候,该字符串就直接排除,不加入待选字符串。
    2. 在当前字符串选择结束后(递归return之前),将当前字符串的长度,也进行计入。(含义:当前字符串之后不再选择,就自己本身也应该进行选择)

    代码参考:

    struct StrInfo{
        int len;
        int aset[26];
    };
    
    class Solution {
    public:
       // int count=0;
       // void print_indent(int count){
       //     for(int i=0; i<count; i++) {
       //         printf("  ");
       //     }
       // }
        void pathappend(StrInfo& path, StrInfo& arrinfo_i) {
            for(int i=0; i<26; i++) {
                if(arrinfo_i.aset[i]!=0) path.aset[i]+=arrinfo_i.aset[i];
            }
            path.len += arrinfo_i.len;
        }
        void pathdelete(StrInfo& path, StrInfo& arrinfo_i) {
            for(int i=0; i<26; i++) {
                if(arrinfo_i.aset[i]!=0) path.aset[i]-=arrinfo_i.aset[i];
            }
            path.len -= arrinfo_i.len;
        }
        bool isValid(StrInfo& arrinfo_i, StrInfo& path) {
            for(int i=0; i<26; i++) {
                if(arrinfo_i.aset[i]!=0 && path.aset[i]!=0) return false;
            }
            return true;
        }
        void backtrack(int& res, StrInfo path, int pos, vector<StrInfo>& arrinfo) {
            if(pos==arrinfo.size()) {
                res = max(res, path.len);
        //        print_indent(count);
        //        printf("return %d
    ", res);
                return;
            }
          //  print_indent(count);
          //  printf("pos %d, path.len: %d
    ", pos, path.len);
            for(int i=pos; i<arrinfo.size(); i++) {
                if(isValid(arrinfo[i], path)) {
                    pathappend(path, arrinfo[i]);
        //            count++;
                    backtrack(res, path, i+1, arrinfo);
        //            count--;
                    pathdelete(path, arrinfo[i]);
                }
            }
            res = max(res, path.len);//注意 2
            //print_indent(count);
            //printf("return final
    ");
            return;
        }
        int maxLength(vector<string>& arr) {
            int res=0;
            vector<StrInfo> arrinfo;
            StrInfo path = {0,{0}};
            for(string s:arr) {
                StrInfo tmp = {0,{0}};
                for(char c:s) {
                    if(tmp.aset[c-'a']!=0) break;//注意 1
                    tmp.aset[c-'a']++;
                    tmp.len++;
                }
                if(tmp.len==s.length())arrinfo.push_back(tmp);//注意 1
            }
            backtrack(res, path, 0, arrinfo);
            return res;
        }
    };
  • 相关阅读:
    微信小程序实战,与后台交互
    微信小程序开发笔记
    微信小程序 之页面跳转
    小程序(四):模板
    (1)Appium基础操作API
    ADB命令
    移动端测试知识概览
    计算机网络常见面试题
    pip命令
    随笔-记录一些简单内容
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/14380568.html
Copyright © 2020-2023  润新知