剑指offer之字符串的排列

本文探讨了如何使用DFS算法解决字符串的字典序排列问题,通过去重和排序实现字符的所有可能组合。介绍了C++和Java两种语言的实现方式,并总结了在回溯过程中保持数据状态的重要性。

剑指offer之字符串的排列

题目描述

输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。

输入描述

输入一个字符串,长度不超过9(可能有字符重复),字符只包括大小写字母。

解题思路

常规dfs,字典序就先sort,还要去重,一开始一直想在根源处去重,无果。然后想着把结果存到set里,能用find函数找到就不push_back,因为没传引用,导致记忆失败。接着没意识到错误,利用map进行标记,失败。后来终于意识到错误,加了引用AC。

Code

class Solution {
public:
    vector<string> Permutation(string str) {
        int len = str.length();
        sort(str.begin(), str.end());
        bool vis[len+1];
        memset(vis, false, sizeof(vis));
        string currentString = "";
        vector<string> res;
        map<string, int> uniqueRes;
        if(str.length()) PermutationCore(vis, currentString, str, res, uniqueRes);
        return res;
    }
    void PermutationCore(bool vis[], string currentString, string str, vector<string> &res, map<string, int> &uniqueRes) {
        int len = str.length();
        if(currentString.length() == len) {
            if(uniqueRes[currentString] == 0) {
                res.push_back(currentString);
                uniqueRes[currentString] = 1;
            }
            return ;
        } 
        for(int i = 0; i<len; i++) {
            if(!vis[i]) {
                vis[i] = 1;
                PermutationCore(vis, currentString+str[i], str, res, uniqueRes);
                vis[i] = 0;
            }
        }
    }
};
  • java
import java.util.ArrayList;
import java.util.TreeSet;
public class Solution {
    private boolean[] vis = new boolean[11];
    private TreeSet<String> result = new TreeSet<String>();
    private StringBuilder sb = new StringBuilder();
    public void dfs(String str) {
        if(sb.length() == str.length()) {
            result.add(sb.toString());
            return ;
        }
        for(int i = 0; i<str.length(); i++) {
            if(!vis[i]) {
                vis[i] = true;
                sb.append(str.charAt(i));
                dfs(str);
                sb.deleteCharAt(sb.length()-1);
                vis[i] = false;
            }
        }
    }
    public ArrayList<String> Permutation(String str) {
        if(str == null || str.length() == 0) return new ArrayList<String>();
        dfs(str);
        return new ArrayList<String>(result);
    }
}

总结

  1. 没有传引用在回溯后就会失去之前存过的数据
  2. 字符串判空
  • java

1 str == null;
2 “”.equals(str);
3 str.length <= 0;
4 str.isEmpty();

  • cpp
     str.empty() || !str.size() || !str.length() || str == ""
    
  1. 补充一点StringBuilder的知识
  • 线程不安全
  • sb.length()
  • .append(ch)
  • .deleteCharAt(sb.length()-1)
  • .setLength(sb.length()-1)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值