• 【剑指Offer】面试题38. 字符串的排列


    题目

    输入一个字符串,打印出该字符串中字符的所有排列。
    你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。

    示例:

    输入:s = "abc"
    输出:["abc","acb","bac","bca","cab","cba"]
    

    限制:1 <= s 的长度 <= 8

    思路一:回溯+无序set去重

    将字符串分为两部分,第一部分为第一个字符,第二部分为后面所有字符。求整个字符串的全排列,可以看成两步,第一步求所有可能出现在第一个位置的字符,即把第一个字符和后面所有字符交换。第二步,固定第一个字符,求后面所有字符排列。
    比如字符串“abc”,
    第一部分为字符a,第二部分为“bc”,首先a在第一个字符,求字符串“bc”的所有全排列得到:
    abc
    acb
    然后交换a和b,b放在第一个字符,求"ac"所有全排列得到:
    bac
    bca
    还原a和b
    再交换a和c,c放在第一个字符,求“ba”所有全排列得到:
    cba
    cab

    代码

    class Solution {
        unordered_set<string> st;
    public:
        vector<string> permutation(string s) {
            vector<string> res;        
            if (s.empty()) return res;                    
            dfs(s, 0, res);
            return res;
        }
    
        void dfs(string &s, int i, vector<string> &res) {        
            if (i == s.size()) {
                if (st.count(s) == 0) {
                    res.push_back(s);
                    st.insert(s);
                }
                return;
            }
            for (int j = i; j < s.size(); ++j) {
                swap(s[j], s[i]);  // 第一个字符和后面所有字符交换
                dfs(s, i + 1, res);  // 求后面字符所有排列
                swap(s[j], s[i]);  // 回溯
            }
        }
    };
    

    优化

    利用函数判断重复元素

    class Solution {    
    public:
        vector<string> permutation(string s) {
            vector<string> res;                
            if (s.empty()) return res;                     
            helper(s, 0, res);
            return res;
        }
    
        void helper(string &s, int pos, vector<string> &res) {        
            if (pos == s.size()) {
                res.push_back(s);
                return;
            } 
            for (int i = pos; i < s.size(); ++i) {
                if (dup(s, pos, i)) continue;  // 在pos到i之间存在重复元素则跳过
                swap(s[pos], s[i]);
                helper(s, pos + 1, res);
                swap(s[pos], s[i]);
            }
        }
    
        bool dup(string &s, int start, int end) {
            for (int i = start; i < end; ++i) {
                if (s[i] == s[end]) return true;
            }
            return false; 
        }
    };
    
  • 相关阅读:
    天猫弹性导航栏
    php 中构造函数和析构函数
    web服务器集群(多台web服务器)后session如何同步和共享
    mycat中schema.xml的一些解释
    mycat高可用集群搭建
    mycat水平分表
    mycat实现mysql数据库的垂直切分
    高并发、大流量解决方案
    nginx负载均衡六种策略
    mysql主从复制实现
  • 原文地址:https://www.cnblogs.com/galaxy-hao/p/12891954.html
Copyright © 2020-2023  润新知