剑指Offer:字符串的排列Java/Python

1.题目描述

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

2.算法描述

回溯的思想,用递归实现。所有的字符都可以放在第1个位置,在选择某个字符放在第1个位置之后,剩下的字符的全排列又可以看作是一个同样的问题。
1)初始遍历第idx(idx初始为1)个位置的所有可能,即将第i个字符与后面的所有字符交换位置。
2)固定第idx个位置的,求从idx+1开始的子序列的全排列(即递归idx+1)。

3.代码描述

3.1.Java代码

import java.util.*;
public class Solution {
    public ArrayList<String> Permutation(String str) {
        ArrayList<String> ans = new ArrayList<>();
        if(str == null || str.length() == 0)//如果字符串为空则直接返回
            return ans;
        helper(ans, 0, str.toCharArray());//从第1个位置开始递归
        Collections.sort(ans);//按字典序排序
        return ans;
    }
    private void helper(ArrayList<String> list, int idx, char[] arr){
        if(idx == arr.length-1){//如果idx到了最后一个字符了 说明找到一个排列
            String s = String.valueOf(arr);
            if(!list.contains(s))//如果这个排列不在答案列表中
                list.add(s);
        }
        else{
            for(int i=idx; i<arr.length; i++){//将第i个位置字符和后续所有字符进行交换
                swap(arr, idx, i);//交换第idx个位置和第i个位置的字符
                helper(list, idx+1, arr);//固定了第idx个位置,递归地寻找子序列的全排列
                swap(arr, idx, i);//交换回来 以便将第idx个位置字符和后续另一个字符进行交换
            }
        }
    }
    private void swap(char[] arr, int i, int j){
        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

3.2.Python代码

# -*- coding:utf-8 -*-
class Solution:
    def Permutation(self, ss):
        # write code here
        ans = []
        if not ss:
            return ans
        self.helper(ans, 0, list(ss))
        ans.sort()
        return ans
    def helper(self, lst, idx, chars):
        if idx == len(chars)-1:
            if ''.join(chars) not in lst:
                lst.append(''.join(chars))
        else:
            for i in range(idx, len(chars)):
                chars[i], chars[idx] = chars[idx], chars[i]
                self.helper(lst, idx+1, chars)
                chars[i], chars[idx] = chars[idx], chars[i]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值