LeetCodeday03

本文解析了多个经典算法题目,包括子集生成、二叉搜索树节点删除、罗马数字转换、交替位二进制数验证等,并提供了详细的代码实现。

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;
    }
}
  1. 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];
    }
  1. 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);
        }
	}
  1. 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;
    }
}
  1. 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";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值