有的题目需要开通会员才可以做 所以暂时先跳过。
点击链接可跳转到所有刷题笔记的导航链接
给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果。你需要给出所有可能的组合的结果。有效的运算符号包含 +, - 以及 * 。
HashMap<String,List<Integer>> map = new HashMap<>();//用于记录已经递归过的字符串。
public List<Integer> diffWaysToCompute(String input) {
List<Integer> res = new ArrayList<>();
if(input.length() == 0)
return res;
int index = 0;
int number = 0;
while(index < input.length() && !isOpt(input.charAt(index))){
//寻找完整数字,在字符串范围内,且当前字符不是运算符
number = number*10+input.charAt(index) - '0';
index++;
}
// 若找到的数字的长度和input长度一致,则将其加入map中 并返回结果
if(index == input.length()){
res.add(number);
map.put(input,res);
return res;
}
// 寻找分割点,运算符作为分割点,将其分为左右两个小的字符串。分别去寻找两个子串可得到的结果
for(int i = 0 ; i<input.length(); i++){
if(isOpt(input.charAt(i))){
List<Integer> left = diffWaysToCompute(input.substring(0,i));//左子串
List<Integer> right = diffWaysToCompute(input.substring(i+1));//右子串
for(Integer number1:left){
//遍历左右子串的结果,汇总
for(Integer number2:right){
res.add(cal(number1,number2,input.charAt(i)));
}
}
}
}
map.put(input,res);//将得到的结果集添加到map中
return res;//返回结果集
}
//计算
public int cal(int number1,int number2,char opt){
if(opt == '*')
return number1 * number2;
else if(opt == '+')
return number1 + number2;
else if(opt == '-')
return number1 - number2;
else return 0;
}
///判断是否是运算符
public boolean isOpt(char n){
return n == '+' || n == '-' || n == '*';
}
分析
1.首先准备一个hashMap,用来记录字符串对应的结果集,这样在遇到相同字符串的时候,就直接返回结果集即可。
2.判断当前字符串是不是仅仅是数字,是的话加入map并返回结果
3.寻找字符串input的分割点,运算符作为分割点,将其分为左右子串
4.然后递归的去寻找左右子串的结果集。
5.找到之后遍历左右子串的结果集,得到该字符串input的结果集。
6.同理将找到的input对应的结果集添加到map中 返回结果集。
7.递归出口就是字符串为空或者是纯数字。
提交结果
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
//方法一
public boolean isAnagram(String s, String t) {
if(s.length()!=t.length())return false;
HashMap<Character,Integer> map = new HashMap<>();
int len = s.length();
for(int i = 0;i<len;i++){
char ch = s.charAt(i);
if(map.containsKey(ch))
map.put(ch,map.get(ch)+1);
else map.put(ch,1);
}
len = t.length();
for(int i = 0;i<len;i++){
char ch = t.charAt(i);
if(map.containsKey(ch)){
int n = map.get(ch) -1;
if(n==0)map.remove(ch);
else map.put(ch,n);
}else return false;
}
return map.keySet().size() == 0;
}
//方法二
public boolean isAnagram(String s, String t) {
if(s.length()!=t.length())return false;
int[] counters = new int[26];
for(int i =0;i<s.length();i++){
counters[s.charAt(i)-'a']++;
counters[t.charAt(i)-'a']--;
}
for(int number : counters){
if(number != 0)return false;
}
return true;
}
//方法三
public boolean isAnagram(String s, String t) {
if(s.length()!=t.length())return false;
char[] chars1 = s.toCharArray();
char[] chars2 = t.toCharArray();
Arrays.sort(chars1);
Arrays.sort(chars2);
return Arrays.equals(chars1,chars2);
}
分析
方法一
方法二
方法三
提交结果
方法一
方法二
方法三
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
backTrack(root,res,"");
return res;
}
public void backTrack(TreeNode root,List<String> res,String tmp){
if(root == null)return;
if(root.left == null && root.right == null){
tmp += root.val;
res.add(tmp);
return;
}else tmp = tmp + root.val + "->";
backTrack(root.left,res,tmp);
backTrack(root.right,res,tmp);
}
给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。
//方法一
public int addDigits(int num) {
if(num<10)return num;
int res = 0;
while(num > 0){
res += num%10;
num /=10;
}
return addDigits(res);
}
//方法二
public int addDigits(int num) {
return (num - 1) % 9 + 1;
}
分析
方法一
1.小于10 直接返回
2.否则将各位数相加后 结果递归
方法二
1.模9法
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
//方法一
public int[] singleNumber(int[] nums) {
Arrays.sort(nums);
int[] res = new int[2];
res[1] = nums[nums.length-1];
int index = 0;
for(int i=0;i <nums.length-1;){
if(nums[i] != nums[i+1]){
res[index++] = nums[i++];
if(index == 2) return res;
}else{
int tmp = nums[i];
while(tmp == nums[i])
i++;
}
}
return res;
}
//方法二
public int[] singleNumber(int[] nums) {
Map<Integer, Integer> hashmap = new HashMap();
for (int n : nums)
hashmap.put(n, hashmap.getOrDefault(n, 0) + 1);
int[] res = new int[2];
int idx = 0;
for (Map.Entry<Integer, Integer> item : hashmap.entrySet())
if (item.getValue() == 1) res[idx++] = item.getKey();
return res;
}
//方法三
public int[] singleNumber(int[] nums) {
int bitmask = 0;
for (int num : nums) bitmask ^= num;
int diff = bitmask & (-bitmask);
int x = 0;
for (int num : nums) if ((num & diff) != 0) x ^= num;
return new int[]{
x, bitmask^x};
}
分析
方法一
方法二
方法三
将数组的值全部异或,得到的结果bitmask中记录了两个出现一次的数字的差异
bitmask & (-bitmask) 保留了最右边的1,这个1来自其中一个数字 。-bitmask = ~bitmask+1
根据这一为的不同,可以将数组分成两堆,再其中一堆中,进行异或,即可找到出现一次的数字
然后和bitmask 进行异或即可得到另一个数字。
提交结果
方法一
方法二
方法三