Anagrams 字符串回文组合 cyber-dojo 编程操练

本文介绍了一种使用Java实现字符串所有可能的全排列的方法。通过自定义的Letter类和LetterHandler辅助类,实现了字符串的拆分与重组,最终生成了输入字符串的所有全排列组合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是编程操练的一道题目。题目是:

Write a program to generate all potential 
anagrams of an input string.

For example, the potential anagrams of "biro" are

biro bior brio broi boir bori
ibro ibor irbo irob iobr iorb
rbio rboi ribo riob roib robi
obir obri oibr oirb orbi orib

接下来是我的编程实现,这是我设计与重构 的最后版本,或许还会重构,我会发布到Github网站上,这是链接,欢迎一起讨论。https://github.com/Blue-Child/Anagrams

Letter类:

//单词或字母
public class Letter {
	
	private String content;
	
	public Letter(String content) {
		this.content = content;
	}
	
	@Override
	public String toString() {
		return this.getContent();
	}

	public String getContent() {
		return content;
	}

	
}
LetterHandler类:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//letter的协助类
public class LetterHandler {

	//处理字符串,得到回文字符串组合(形式:分隔+组合)
	public static Map<String, Letter> handler(String anagram) {
		List<Letter> letterList = split(anagram);
		Map<String, Letter> letterMap = composite(letterList);
		return letterMap;
	}

	//分隔字符串
	private static List<Letter> split(String anagram) {
		List<Letter> letterList = new ArrayList<Letter>();
		for (int i = 0; i < anagram.length(); i++) {
			char c = anagram.charAt(i);
			Letter letter = new Letter(c + "");
			letterList.add(letter);
		}
		return letterList;
	}
	
	//排列组合字符串回文
	private static Map<String, Letter> composite(List<Letter> letterList) {
		Map<String, Letter> letterMap = new HashMap<String, Letter>();
		recComposite(letterList, letterMap, "", new int[]{});
		return letterMap;
	}
	
	//递归组合字符串回文
	private static void recComposite(List<Letter> letterList, Map<String, Letter> letterMap, String beforeStr, int[] targetIndex) {
		for (int k = 0; k < letterList.size(); k++) {
			String composite = "";
			if (!isContainSameIndex(k, targetIndex)) {
				composite = beforeStr + letterList.get(k);  
				if (isTheLastChar(targetIndex, letterList)) {
					addToMap(letterMap, composite);
					break;
				} else {
					int[] targetIndexs = appendTargetIndexs(k, targetIndex);
					recComposite(letterList, letterMap, composite, targetIndexs);
				}
			} else {
				continue;
			}
		}
	}

	//判断下标是否一样
	private static boolean isContainSameIndex(int sourceIndex, int... targetIndex) {
		for (int i = 0; i < targetIndex.length; i++) {
			int target = targetIndex[i];
			if (sourceIndex == target) {
				return true;
			}
		}
		return false;
	}

	//判断是否是最后一个字符
	private static boolean isTheLastChar(int[] targetIndex, List<Letter> letterList) {
		return (targetIndex.length + 1) == (letterList.size());
	}
	
	//将字符串排列结果添加到map中
	private static void addToMap(Map<String, Letter> letterMap, String composite) {
		letterMap.put(composite, new Letter(composite));
	}
	
	//组转下标数组
	private static int[] appendTargetIndexs(int beforeIndex, int[] targetIndex) {
		int[] targetIndexs = new int[targetIndex.length + 1];
		targetIndexs[0] = beforeIndex;
		for (int i = 0; i < targetIndex.length; i++) {
			targetIndexs[i + 1] = targetIndex[i];
		}
		return targetIndexs;
	}
	
	//展示
	public static void show(Map<String, Letter> letterMap) {
		int n = 0;
		for (String key : letterMap.keySet()) {
			Letter letter = letterMap.get(key);
			System.out.print(letter.toString() + "	");
			if ((++n % 6) == 0) {
				System.out.println();
			}
		}
	}
}
LetterTest测试类:

import java.util.Map;

import org.junit.Test;

public class LetterTest {
	
	@Test
	public void testAnagramWithFour() {
		String anagram = "biro";
		Map<String, Letter> letterMap = LetterHandler.handler(anagram);
		LetterHandler.show(letterMap);
	}
	
	@Test
	public void testAnagramWithFourHasSameLetter() {
		String anagram = "bibo";
		Map<String, Letter> letterMap = LetterHandler.handler(anagram);
		LetterHandler.show(letterMap);
	}
	
	@Test
	public void testAnagramWithFive() {
		String anagram = "biroe";
		Map<String, Letter> letterMap = LetterHandler.handler(anagram);
		LetterHandler.show(letterMap);
	}
}
总结:不断的进行编程操练,可以巩固设计方面和重构方面的知识,提高编程设计能力。



### 关于字符串 LeetCode 算法题解决方案 解决字符串相关的 LeetCode 题目通常涉及多种技巧,包括但不限于双指针、滑动窗口、哈希表以及动态规划等方法。以下是几个常见的字符串处理问题及其可能的解法。 #### 1. 双指针技术 对于一些需要比较两个字符串或者在一个字符串中寻找特定子串的问题,可以采用双指针技术来优化时间复杂度。例如,在判断回文字符串时,可以通过设置头尾两个指针逐步向中间移动并对比字符是否相等[^1]。 ```python def is_palindrome(s: str) -> bool: left, right = 0, len(s) - 1 while left < right: if not s[left].isalnum(): left += 1 continue if not s[right].isalnum(): right -= 1 continue if s[left].lower() != s[right].lower(): return False left += 1 right -= 1 return True ``` #### 2. 滑动窗口算法 当题目涉及到连续子数组或子字符串的最大最小长度等问题时,滑动窗口是一种非常有效的策略。比如求解最长无重复字符子串问题就可以利用此方法实现O(n)的时间效率[^2]。 ```python def length_of_longest_substring(s: str) -> int: char_index_map = {} max_length = start = 0 for i, c in enumerate(s): if c in char_index_map and start <= char_index_map[c]: start = char_index_map[c] + 1 else: max_length = max(max_length, i - start + 1) char_index_map[c] = i return max_length ``` #### 3. 哈希表应用 许多关于查找某个模式是否存在或者统计频率类别的题目都可以借助哈希结构快速完成操作。像字母异位词分组这样的挑战就非常适合通过构建字典来进行分类存储[^3]。 ```python from collections import defaultdict def group_anagrams(strs: list[str]) -> list[list[str]]: anagram_dict = defaultdict(list) for string in strs: key = ''.join(sorted(string)) anagram_dict[key].append(string) return list(anagram_dict.values()) ``` #### 4. 动态规划思路 某些复杂的编辑距离计算或者是序列匹配类型的习题则需要用到动态规划的思想去分解成更小规模的状态转移方程解答[^4]。 ```python def min_distance(word1: str, word2: str) -> int: m, n = len(word1), len(word2) dp = [[0]*(n+1) for _ in range(m+1)] for i in range(1,m+1): dp[i][0]=i for j in range(1,n+1): dp[0][j]=j for i in range(1,m+1): for j in range(1,n+1): if word1[i-1]==word2[j-1]: cost=0 else:cost=1 dp[i][j]=min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+cost) return dp[m][n] ``` 以上仅列举了几种典型场景下的编程实践案例供参考学习之用。每道具体的LeetCode题目都有其独特的背景设定和边界条件考量因素,因此实际编码过程中还需要仔细审阅题目描述,并充分测试各种极端情况下的表现效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值