90.Subsets II
class Solution {
public List<List<Integer>> subsetsWithDup(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new ArrayList<>();
List<Integer> each = new ArrayList<>();
helper(res, each, 0, nums);
return res;
}
private void helper(List<List<Integer>> res, List<Integer> each, int pos, int[] n) {
if (pos <= n.length)
res.add(each);
int i = pos;
while (i < n.length) {
each.add(n[i]);
helper(res, new ArrayList<>(each), i + 1, n);
each.remove(each.size() - 1);
i++;
while (i < n.length && n[i] == n[i - 1]) {
i++;
}
}
return;
}
}
450、 Delete Node in a BST
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null)
return null;
//和值不同就取与值更相近的数进行下次递归
if(root.val>key){
root.left = deleteNode(root.left,key);
}else if(root.val<key){
root.right = deleteNode(root.right,key);
}else{
if(root.right==null){
return root.left;
}
if(root.left == null){
return root.right;
}
//取比相等值大的最相近的数来替换被删除的值
TreeNode minNode = findMin(root.right);
root.val = minNode.val;
root.right = deleteNode(root.right, root.val);
}
return root;
}
public static TreeNode findMin(TreeNode node){
//需要使用while来获取最小 使用if只判断一次 会取错
while(node.left != null){
node = node.left;
}
return node;
}
}
720、Longest Word in Dictionary
//获取包含最多的字符 且长的
class Solution {
public String longestWord(String[] words) {
Arrays.sort(words);
Set<String> built = new HashSet<String>();
String res = "";
for (String w : words) {
if (w.length() == 1 || built.contains(w.substring(0, w.length() - 1))) {//length()==1是加入一个为了进行包含判断?
res = w.length() > res.length() ? w : res;//保存获取的最长字符
built.add(w);
}
}
return res;
}
}
12、Integer to Roman
//int转换成罗马数
class Solution {
public static String intToRoman(int num) {
String M[] = {"", "M", "MM", "MMM"};
String C[] = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"};
String X[] = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"};
String I[] = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"};
return M[num/1000] + C[(num%1000)/100] + X[(num%100)/10] + I[num%10];
}
}
693、Binary Number with Alternating Bits
//int转换成二进制后是否间隔10输出
class Solution {
public boolean hasAlternatingBits(int n) {
//int转换成二进制的
String a = Integer.toBinaryString(n);
//下标可能越界
for(int i =0 ;i<a.length()-1;i++){
//通过转化后的二进制数的对比如果相同就输出错
if(a.charAt(i)==a.charAt(i+1)) return false;
}
return true;
}
}
class Solution {
public boolean hasAlternatingBits(int n) {
int cur = n % 2;
//相当于右移一格然后比较最后一位是否相同 因为2个如果相同就代表全为同一个数 返回false
n /= 2;
while (n > 0) {
if (cur == n % 2) return false;
cur = n % 2;
n /= 2;
}
return true;
}
}
- Concatenated Words
//将由其他字符组成的数输出 使用字典树查找
public List<String> findAllConcatenatedWordsInADict(String[] words) {
List<String> res = new ArrayList<String>();
if (words == null || words.length == 0) {
return res;
}
TrieNode root = new TrieNode();
for (String word : words) { // construct Trie tree
if (word.length() == 0) {
continue;
}
addWord(word, root);
}
for (String word : words) { // test word is a concatenated word or not
if (word.length() == 0) {
continue;
}
if (testWord(word.toCharArray(), 0, root, 0)) {
res.add(word);
}
}
return res;
}
public boolean testWord(char[] chars, int index, TrieNode root, int count) { // count means how many words during the search path
TrieNode cur = root;
int n = chars.length;
for (int i = index; i < n; i++) {
if (cur.sons[chars[i] - 'a'] == null) {
return false;
}
if (cur.sons[chars[i] - 'a'].isEnd) {
if (i == n - 1) { // no next word, so test count to get result.
return count >= 1;
}
if (testWord(chars, i + 1, root, count + 1)) {
return true;
}
}
cur = cur.sons[chars[i] - 'a'];
}
return false;
}
public void addWord(String str, TrieNode root) {
char[] chars = str.toCharArray();
TrieNode cur = root;
for (char c : chars) {
if (cur.sons[c - 'a'] == null) {
cur.sons[c - 'a'] = new TrieNode();
}
cur = cur.sons[c - 'a'];
}
cur.isEnd = true;
}
}
class TrieNode {
TrieNode[] sons;
boolean isEnd;
public TrieNode() {
sons = new TrieNode[26];
}
- Sort Characters By Frequency
//按照出现的频率排序一个字符串
public static void main(String[] args) {
String s = "aaaahdfjf";
Map<Character,Integer> map = new HashMap<>();
for(char c:s.toCharArray())//将字符串转换成一个新的字符数组
map.put(c,map.getOrDefault(c,0)+1);//1.8才出现的可以返回到指定键所映射的值,或 defaultValue如果此映射包含该键的映射
List<Character> [] bucket = new List[s.length()+1];
for(char key:map.keySet()){
int frequency = map.get(key);
if(bucket[frequency] == null) bucket[frequency] = new ArrayList<>();//用于给每个字符添加个动态数组用来保存出现频率次数
bucket[frequency].add(key);
}
StringBuilder sb= new StringBuilder();
for(int pos = bucket.length-1;pos>=0;pos--){//从大到小从数组中提取字符然后打印
if(bucket[pos]!=null)
for(char c:bucket[pos])
for(int i=0;i<map.get(c);i++)
sb.append(c);
}
}
- Valid Anagram
//看一个字符串是否是另外一个字符串改变字符顺序
class Solution {
public boolean isAnagram(String s, String t) {
Map<Character,Integer> map = new HashMap<>();
Map<Character,Integer> map1 = new HashMap<>();
for(Character c:s.toCharArray()){
map.put(c,map.getOrDefault(c,0)+1);
}
for(Character c:t.toCharArray()){
map1.put(c,map1.getOrDefault(c,0)+1);
}
return map.equals(map1);
}
}
//通过排序区分是否改变
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) {
return false;
}
char[] str1 = s.toCharArray();
char[] str2 = t.toCharArray();
Arrays.sort(str1);
Arrays.sort(str2);
return Arrays.equals(str1, str2);
}
//通过字符是否有相同个数来判别 效率高而且可以应对大小写
class Solution {
public boolean isAnagram(String s, String t) {
if(s.length()!=t.length()) return false;
int[] chars = new int[26];
for(int i=0;i<s.length();i++) {
chars[s.charAt(i)-'a']++;
chars[t.charAt(i)-'a']--;
}
for(int count:chars) if(count!=0) return false;
return true;
}
}
- Bulls and Cows
//猜有几个数在正确位置几个没在,如果数字不存在答案中不输出 A为正确个数B为错误个数
class Solution {
public String getHint(String secret, String guess) {
int bulls = 0,cows = 0;
int[] nums = new int[10];
for(int i = 0;i<secret.length();i++){
if(secret.charAt(i) == guess.charAt(i)) bulls++;
else{//如果某个数不在指定位置而在另外的位置找出来的话,就会因为上次的变动而大于或者小于0导致cows增加
if(nums[secret.charAt(i)-'0']-->0) cows++;
if(nums[guess.charAt(i)-'0']++<0) cows++;
}
}
return bulls+"A"+cows+"B";
}
}
本文解析了多个经典算法题目,包括子集生成、二叉搜索树节点删除、罗马数字转换、交替位二进制数验证等,并提供了详细的代码实现。
350

被折叠的 条评论
为什么被折叠?



