leetcode每日一题

ps:今天的每日一题没意思,简单的模拟,自己换一道

面试题 08.04. 幂集

幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]

题解:

class Solution {List<List<Integer>> list;public List<List<Integer>> subsets(int[] nums) {list=new ArrayList();dfs(nums.length-1,nums,new ArrayList<Integer>());return list;}void dfs(int n,int[] nums,List<Integer> list2){if(n<0){list.add(new ArrayList<Integer>(list2));return;}list2.add(nums[n]);dfs(n-1,nums,list2);list2.remove(list2.size()-1);dfs(n-1,nums,list2);}
}

练习题1

面试题 01.09. 字符串轮转

字符串轮转。给定两个字符串s1和s2,请编写代码检查s2是否为s1旋转而成(比如,waterbottle是erbottlewat旋转后的字符串)。

示例1:

输入:s1 = “waterbottle”, s2 = “erbottlewat”
输出:True
示例2:

输入:s1 = “aa”, s2 = “aba”
输出:False

class Solution {public boolean isFlipedString(String s1, String s2) {int len1 = s1.length();int len2 = s2.length();if(len1 != len2)    return false;String s3 = s1+ s1;for(int i = 0;i < s3.length()-len2;i++){String s4 = s3.substring(i,i+len2);if(s4.equals(s2)){return true;}}return s1.equals(s2)?true:false;}
}
class Solution {public boolean isFlipedString(String s1, String s2) {return s1.length() == s2.length() && (s2 + s2).contains(s1);}
}

练习题2

648. 单词替换

在英语中,我们有一个叫做 词根(root) 的概念,可以词根后面添加其他一些词组成另一个较长的单词——我们称这个词为 继承词(successor)。例如,词根an,跟随着单词 other(其他),可以形成新的单词 another(另一个)。

现在,给定一个由许多词根组成的词典 dictionary 和一个用空格分隔单词形成的句子 sentence。你需要将句子中的所有继承词词根替换掉。如果继承词有许多可以形成它的词根,则用最短的词根替换它。

你需要输出替换之后的句子。

示例 1:

输入:dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
输出:"the cat was rat by the bat"

示例 2:

输入:dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
输出:"a a b c"
class Solution {public String replaceWords(List<String> dict, String sentence) {int len = dict.size();int len1 = sentence.length();String[] s = sentence.split(" ");                             StringBuffer str = new StringBuffer();for (int i = 0;i < s.length;i++){for(int j = 0;j < len;j++){int len2 = dict.get(j).length();if(s[i].length() < len2){continue;}String temp = s[i].substring(0,len2);if(temp.equals(dict.get(j))){s[i] = dict.get(j);}}str.append(s[i]);str.append(" ");}return str.toString().substring(0,str.length()-1);}
}

ps:咔咔一顿暴力,给暴力求解出来了,很意外

主要的思路就是把句子变成数组,然后遍历数组,判断list集合中有没有,有的话就代替(tip:因为找的是词根,所以截取单词前面的部分就行,另外,如果有可能句子的单词太短,那么就直接跳过)

题解:

前缀哈希

class Solution {public String replaceWords(List<String> roots, String sentence) {Set<String> rootset = new HashSet();for (String root: roots) rootset.add(root);StringBuilder ans = new StringBuilder();for (String word: sentence.split("\\s+")) {String prefix = "";for (int i = 1; i <= word.length(); ++i) {prefix = word.substring(0, i);if (rootset.contains(prefix)) break;}if (ans.length() > 0) ans.append(" ");ans.append(prefix);}return ans.toString();}
}

ps:这个前缀哈希,提交之后,不是很理想,时间大幅度增长了,但是内存节省了一点

仔细看题解之后发现跟我的暴力就是多加了一层hashset去重,时间复杂度的提升主要就在rootset.contains这一行了,去遍历内部是否存在,直接将时间复杂度翻倍了

前缀树

class Solution {public String replaceWords(List<String> roots, String sentence) {TrieNode trie = new TrieNode();for (String root: roots) {TrieNode cur = trie;for (char letter: root.toCharArray()) {if (cur.children[letter - 'a'] == null)cur.children[letter - 'a'] = new TrieNode();cur = cur.children[letter - 'a'];}cur.word = root;}StringBuilder ans = new StringBuilder();for (String word: sentence.split("\\s+")) {if (ans.length() > 0)ans.append(" ");TrieNode cur = trie;for (char letter: word.toCharArray()) {if (cur.children[letter - 'a'] == null || cur.word != null)break;cur = cur.children[letter - 'a'];}ans.append(cur.word != null ? cur.word : word);}return ans.toString();}
}class TrieNode {TrieNode[] children;String word;TrieNode() {children = new TrieNode[26];}
}

ps:时间复杂度降下来了,空间复杂度提升上去了

前缀树不会,开始刷前缀树的题

练习题3

剑指 Offer II 062. 实现前缀树

Trie(发音类似 “try”)或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。

请你实现 Trie 类:Trie() 初始化前缀树对象。

void insert(String word) 向前缀树中插入字符串 word 。

boolean search(String word) 如果字符串 word 在前缀树中,返回 true(即,在检索之前已经插入);否则,返回 false 。

boolean startsWith(String prefix) 如果之前已经插入的字符串 word 的前缀之一为 prefix ,返回 true ;否则,返回 false 。

学习前缀树

Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较。

Trie的核心思想是空间换时间。利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。

前缀树的3个基本性质:

  1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
  2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符都不相同。
public class Trie {// 记录前缀树的根节点TreeNode root;// 定义前缀树节点class TreeNode{TreeNode[] next;boolean isEnd;public TreeNode (){next = new TreeNode[26];}}// 初始化前缀树public Trie() {root = new TreeNode();}// 插入public void insert(String word) {TreeNode cur = root;for(char ch : word.toCharArray()){// 判断对应节点是否为空,如果为空,则直接插入if(cur.next[ch - 'a'] == null){cur.next[ch - 'a'] = new TreeNode();}// 继续插入下一个节点cur = cur.next[ch - 'a'];}// 将最后一个字符设置为结尾cur.isEnd = true;}// 查找单词public boolean search(String word) {TreeNode cur = root;for(char ch : word.toCharArray()){// 如果对应节点为空,则表明不存在这个单词,返回falseif(cur.next[ch - 'a'] == null)return false;cur = cur.next[ch - 'a'];}// 检查最后一个字符是否是结尾return cur.isEnd;}// 查找前缀public boolean startsWith(String prefix) {TreeNode cur = root;for(char ch : prefix.toCharArray()){if(cur.next[ch - 'a'] == null)return false;cur = cur.next[ch - 'a'];}return true;}
}

leetcode每日一题--前缀树;前缀哈希;深搜;面试题 08.04. 幂集;648. 单词替换面试题 01.09. 字符串轮转;剑指 Offer II 062. 实现前缀树相关推荐

  1. 剑指Offer(Python多种思路实现):树的子结构

    剑指Offer(Python多种思路实现):树的子结构 面试26题: 题目:树的子结构 题:输入两棵二叉树A和B,判断B是不是A的子结构. 解题思路一:递归,注意空指针的情况. class Solut ...

  2. Leetcode刷题笔记——剑指offer II (五)【二分、排序、回溯】

    这里写目录标题 二分查找 剑指 Offer II 069. 山峰数组的顶部 剑指 Offer II 070. 排序数组中只出现一次的数字 剑指 Offer II 071. 按权重生成随机数 剑指 Of ...

  3. 【算法leetcode每日一练】剑指 Offer II 080. 含有 k 个元素的组合 | 77. 组合

    文章目录 剑指 Offer II 080. 含有 k 个元素的组合 | 77. 组合: 样例 1: 样例 2: 提示: 分析 题解 java c c++ python go rust javascri ...

  4. LeetCode Algorithm 剑指 Offer II 056. 二叉搜索树中两个节点之和

    剑指 Offer II 056. 二叉搜索树中两个节点之和 Ideas 这题有点类似一个组合题,首先是通过二叉树遍历得到一个序列,然后再通过LeetCode Algorithm 1. 两数之和的方法查 ...

  5. LeetCode 21.23.剑指 Offer II 078. 合并两个有序链表 | C语言版

    LeetCode 21. 合并两个有序链表 | C语言版 LeetCode 21. 合并两个有序链表 题目描述 解题思路 思路一:使用栈 代码实现 运行结果 参考文章: 思路二:减少遍历节点数 代码实 ...

  6. LeetCode 剑指 Offer II 前缀树(上) 专题总结

  7. LeetCode每日一题(2022/5/31)剑指 Offer II 114. 外星文字典(困难)

    现有一种使用英语字母的外星文语言,这门语言的字母顺序与英语顺序不同. 给定一个字符串列表 words ,作为这门语言的词典,words 中的字符串已经 按这门新语言的字母顺序进行了排序 . 请你根据该 ...

  8. 打牌博弈 dfs深度优先遍历搜索 排课表 拓扑排序 升序字符串 动态规划 剑指offer编程题整理 leetcode每日算法题

    递归,回溯, 深度优先搜索 题目描述 有一叠扑克牌,每张牌介于1和10之间 有四种出牌方法: 单出1张 出2张对子 出五张顺子,如12345 出三连对子,如112233 给10个数,表示1-10每种牌 ...

  9. 【剑指Offer题解:java】树的子结构

    文章目录 题目 分析 代码 题目 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 分析 先序遍历树 A中的每个节点node1 判断树A中以node1为根节点 ...

最新文章

  1. 乔布斯诞辰67周年,他的这些思想仍值得我们学习
  2. 应用分析:CIO须注意SOA使用中的五大隐患
  3. vscode vue解决跨域_在vs code 中如何创建一个自己的 Vue 模板代码
  4. layer + ajax 弹出框
  5. RHEL 7.0系统安装配置图解教程
  6. matlab2016 b 安装详细教程正版中文密钥
  7. Kubernetes学习笔记 黑马程序员
  8. 外贸小公司如何做谷歌SEO优化
  9. 天刀计算机中丢失,天涯明月刀手游失踪白兔奇遇任务攻略
  10. [淘宝客技术篇003]如何获取淘客私密优惠券链接
  11. asp.net mvc 实现判断用户是否登录的两种方式
  12. 年度成绩大赏|2021,StreamNative 扬帆起航
  13. 基于C#实现的《勇士返乡》游戏设计
  14. 【每日蓝桥】44、一七年省赛Java组真题“纸牌三角形”
  15. AndroidEventBus(事件总线)了解+实战体验
  16. Word文档中实现:点击图片双击放大
  17. 32位驱动安装到64位操作系统时出错
  18. Linux 驱动 | SPI子系统
  19. SDOI2014 Round1 day2
  20. python平均值代码_python中的运行平均值

热门文章

  1. 锐界机器人_钱江机器人/海峰机器人/锐界科技彰显“装配”技术实力
  2. 真实生活的记录:我三年的外企生涯(9) 出处:天涯虚拟社区
  3. 撷半盏时光,叙岁月无恙。
  4. 乐视体感astra pro深度摄像头在ros系统获取 深度图像 彩色图像 无色彩点云数据 彩色点云数据
  5. 21、每日一句API接口,免费好用
  6. 八月六日个人训练记录
  7. OpenGauss一主一从搭建(全网最详细,最简单)
  8. 我为什么不是清华的学生
  9. Docker系列(二十一)——Docker实例三Docker安装Tomcat实例
  10. 4、keil C51多文件创建小记