串联所有单词的子串(哈希表、字符串)、求公式的值(数学、阶乘)、扰乱字符串(字符串、动态规划)

举报
共饮一杯无 发表于 2023/02/28 09:51:22 2023/02/28
【摘要】 串联所有单词的子串(哈希表、字符串)给定一个字符串 s和一些长度相同的单词 words。找出 s中恰好可以由 words中所有单词串联形成的子串的起始位置。注意子串要与 words中的单词完全匹配,中间不能有其他字符,但不需要考虑 words中单词串联的顺序。示例 1:输入: s = "barfoothefoobarman", words = ["foo","bar"]输出:[0,9]...

串联所有单词的子串(哈希表、字符串)

给定一个字符串 s和一些长度相同的单词 words。找出 s中恰好可以由 words中所有单词串联形成的子串的起始位置。
注意子串要与 words中的单词完全匹配,中间不能有其他字符,但不需要考虑 words中单词串联的顺序。

示例 1:

输入:  s = "barfoothefoobarman",  words = ["foo","bar"]
输出:[0,9]
解释:从索引 09 开始的子串分别是 "barfoo""foobar" 。输出的顺序不重要, [9,0] 也是有效答案。

示例 2:

输入:  s = "wordgoodgoodgoodbestword",  words = ["word","good","best","word"]
输出:[]

以下程序实现了这一功能,请你填补空白处内容:

class Solution {
	public List<Integer> findSubstring(String s, String[] words) {
		List<Integer> res = new ArrayList<>();
		if (s == null || s.length() == 0 || words == null || words.length == 0)
			return res;
		HashMap<String, Integer> map = new HashMap<>();
		int one_word = words[0].length();
		int word_num = words.length;
		int all_len = one_word * word_num;
		for (String word : words) {
			map.put(word, map.getOrDefault(word, 0) + 1);
		}
		for (int i = 0; i < one_word; i++) {
			int left = i, right = i, count = 0;
			HashMap<String, Integer> tmp_map = new HashMap<>();
			while (right + one_word <= s.length()) {
				String w = s.substring(right, right + one_word);
				right += one_word;
				if (!map.containsKey(w)) {
					count = 0;
					left = right;
					tmp_map.clear();
				} else {
					tmp_map.put(w, tmp_map.getOrDefault(w, 0) + 1);
					count++;
					while (tmp_map.getOrDefault(w, 0) > map.getOrDefault(w, 0)) {
						______________________;
					}
					if (count == word_num)
						res.add(left);
				}
			}
		}
		return res;
	}
}

解答:

String t_w = s.substring(left, left + one_word);
count--;
tmp_map.put(t_w, tmp_map.getOrDefault(t_w, 0) - 1);
left += one_word;

求公式的值(数学、阶乘)

求 1-1/2!-1/3! -… -1/10!
解答:

public class TEST {
    public static double jiecheng(int n) {
        double s = 1;
        for (int i = 1; i <= n; i++)
            s *= i;
        return s;
    }
    public static double sum(int n) {
        double sum = 0.0;
        int s = 1;
        for (int i = 1; i <= n; i++) {
            sum += s / jiecheng(i);
            s = -s;
        }
        return sum;
    }
    public static void main(String[] args) throws Exception {
        int n = 10;
        double ss = sum(n);
        System.out.println(ss);
    }
}

扰乱字符串(字符串、动态规划)

使用下面描述的算法可以扰乱字符串 s 得到字符串 t :

  1. 如果字符串的长度为 1 ,算法停止
  2. 如果字符串的长度 > 1 ,执行下述步骤:
    • 在一个随机下标处将字符串分割成两个非空的子字符串。即,如果已知字符串 s ,则可以将其分成两个子字符串 x 和 y ,且满足 s = x + y 。
    • 随机 决定是要「交换两个子字符串」还是要「保持这两个子字符串的顺序不变」。即,在执行这一步骤之后,s 可能是 s = x + y 或者 s = y + x 。
    • 在 x 和 y 这两个子字符串上继续从步骤 1 开始递归执行此算法。

给你两个 长度相等 的字符串 s1_ 和 s2,判断 s2 是否是 s1 _的扰乱字符串。如果是,返回 true ;否则,返回 false 。

示例 1:
输入:s1 = “great”, s2 = “rgeat”
输出:true
解释:s1 上可能发生的一种情形是:
“great” --> “gr/eat” // 在一个随机下标处分割得到两个子字符串
“gr/eat” --> “gr/eat” // 随机决定:「保持这两个子字符串的顺序不变」
“gr/eat” --> “g/r / e/at” // 在子字符串上递归执行此算法。两个子字符串分别在随机下标处进行一轮分割
“g/r / e/at” --> “r/g / e/at” // 随机决定:第一组「交换两个子字符串」,第二组「保持这两个子字符串的顺序不变」
“r/g / e/at” --> “r/g / e/ a/t” // 继续递归执行此算法,将 “at” 分割得到 “a/t”
“r/g / e/ a/t” --> “r/g / e/ a/t” // 随机决定:「保持这两个子字符串的顺序不变」
算法终止,结果字符串和 s2 相同,都是 “rgeat”
这是一种能够扰乱 s1 得到 s2 的情形,可以认为 s2 是 s1 的扰乱字符串,返回 true
示例 2:
输入:s1 = “abcde”, s2 = “caebd”
输出:false
示例 3:
输入:s1 = “a”, s2 = “a”
输出:true

提示:

  • s1.length == s2.length
  • 1 <= s1.length <= 30
  • s1 和 s2 由小写英文字母组成

以下程序实现了这一功能,请你填补空白处内容:

class Solution {
	public boolean isScramble(String s1, String s2) {
		if (s1.length() == 0 && s2.length() == 0)
			return true;
		if (s1.length() != s2.length())
			return false;
		return dfs(s1.toCharArray(), s2.toCharArray(), 0, 0, s1.length());
	}
	private boolean dfs(char[] s1, char[] s2, int start1, int start2, int len) {
		if (len == 1) {
			return s1[start1] == s2[start2];
		}
		if (!equals(s1, s2, start1, start2, len)) {
			return false;
		}
		for (int i = 1; i < len; i++) {
			____________________;
		}
		return false;
	}
	public boolean equals(char[] s1, char[] s2, int start1, int start2, int len) {
		int[] charArr = new int[26];
		for (int i = 0; i < len; i++) {
			charArr[s1[start1 + i] - 'a']++;
			charArr[s2[start2 + i] - 'a']--;
		}
		for (int item : charArr) {
			if (item != 0)
				return false;
		}
		return true;
	}
}

解答:

if (dfs(s1, s2, start1, start2, i) && dfs(s1, s2, start1 + i, start2 + i, len - i))
	return true;
if (dfs(s1, s2, start1, start2 + len - i, i) && dfs(s1, s2, start1 + i, start2, len - i))
	return true;

本文内容到此结束了,
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位大佬指出。
保持热爱,奔赴下一场山海。🏃🏃🏃

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。