要开始刷题了!请一定要坚持下去哦

  1. 两数之和
    给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下标。
    你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。

    示例:
    给定 nums = [2, 7, 11, 15], target = 9
    因为 nums[0] + nums[1] = 2 + 7 = 9
    所以返回 [0, 1]

思路: 遍历每一个数,将当前数以及下标存入map中,当一个数是确定的,另一个值必然是确定的。

public class TwoNumSum {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            int other = target - nums[i];
            if(map.containsKey(other)) {
                return new int[]{map.get(other), i};
            }
            map.put(nums[i], i);
        }
        return null;
    }
}

2、两数之和
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

public class SumOfTwoNum {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode head = new ListNode(0);
        ListNode c = head;
        int mod = 0;
        while (l1 != null || l2 != null) {
            int x = l1 != null ? l1.val : 0;
            int y = l2 != null ? l2.val : 0;
            int value = x + y + mod;
            mod = value / 10;
            ListNode temp = new ListNode(value % 10);
            c.next = temp;
            c = c.next;
            if(l1 != null) l1 = l1.next;
            if(l2 != null) l2 = l2.next;
        }
        if(mod > 0) {
            ListNode temp = new ListNode(mod);
            c.next = temp;
        }
        return head.next;
    }
}

3、无重复最长子串
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例:
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
请在这里输入引用内容

class Solution {
     public int lengthOfLongestSubstring(String s) {
        if(s.isEmpty()) return 0;
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < s.length(); i++) {
            Set set = new HashSet<>();
            for (int j = i; j < s.length(); j++) {
                Character c = s.charAt(j);
                if(!set.contains(c)) {
                    set.add(c);
                } else {
                    int value = set.size();
                    if(value > max) {
                        max = value;
                    }
                    break;
                }
            }
            if(set.size() > max) {
                max = set.size();
            }
        }
        return max;
    }
}

4、寻找两个有序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2。
请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。
你可以假设 nums1 和 nums2 不会同时为空。

示例:
nums1 = [1, 3]
nums2 = [2]
则中位数是 2.0

int / double 得到的是 double

class Solution {
       public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        if(nums2.length == 0) {
            if(nums1.length % 2 == 0) {
                return (nums1[nums1.length/2] + nums1[nums1.length/2 - 1])  / 2.0;
            } else {
                return nums1[nums1.length/2];
            }
        } else if (nums1.length == 0){
            if(nums2.length % 2 == 0) {
                return (nums2[nums2.length/2] + nums2[nums2.length/2 - 1]) / 2.0;
            } else {
                return nums2[nums2.length/2];
            }
        }
        int length = nums1.length + nums2.length;
        int[] fin = new int[length];
        int t = 0, i = 0, j = 0;
        double mid = 0;
        while (i < nums1.length && j < nums2.length) {
            if(nums1[i] < nums2[j]) {
                fin[t++] = nums1[i];
                i++;
            } else if(nums1[i] > nums2[j]){
                fin[t++] = nums2[j];
                j++;
            } else {
                fin[t++] = nums1[i];
                fin[t++] = nums2[j];
                i++;
                j++;
            }
        }
        while (i < nums1.length) {
            fin[t++] = nums1[i];
            i++;
        }
        while (j < nums2.length) {
            fin[t++] = nums2[j];
            j++;
        }
        if(length % 2 == 0) {
            mid = (fin[length/2] + fin[length/2 - 1]) / 2.0;
        } else {
            mid = fin[length/2];
        }
        return mid;
    }
}

5、最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

思路:遍历每个元素,从当前元素往两边展开,如果是回文串,则记录长度。

class Solution {
      public static String longestPalindrome(String s) {
        int max = Integer.MIN_VALUE;
        int start = 0;
        int end = 0;
        for (int i = 0; i < s.length(); i++) {
            int rflag = 1, rj, rt;
            for(rj = i-1, rt = i+1; rj >= 0 && rt < s.length() && s.charAt(rj) == s.charAt(rt); rj--,rt++,rflag++);
            int lflag = 0, lt, lj;
            for (lj = i, lt = i+1; lj >= 0 && lt < s.length() && s.charAt(lj) == s.charAt(lt); lj--,lt++,lflag++);
            if(rflag > lflag && rflag > max) {
                max = rflag;
                start = rj+1;
                end = rt;
            }
            if(rflag <= lflag && lflag >= max) {
                max = lflag;
                start = lj+1;
                end = lt;
            }
        }
        return s.substring(start, end);
    }
}

6、Z字形变换
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
比如输入字符串为 "LEETCODEISHIRING" 行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"LCIRETOESIIGEDHN"。
请你实现这个将字符串进行指定行数变换的函数:
string convert(string s, int numRows);

示例:
输入: s = "LEETCODEISHIRING", numRows = 3
输出: "LCIRETOESIIGEDHN"

7、整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例:
输入: 123
输出: 321

class Solution {
        public static int reverse(int x) { //1234
        int dem = x%10; // 4// 123
        long number = 0;
        while (x != 0) { 
           number = number * 10 + dem;
           if(number > Integer.MAX_VALUE || number < Integer.MIN_VALUE) {
               return 0;
           }
           x = x/10; // 123
           dem = x%10; //
        }
        return (int) number;
    }
}

8、字符串转换整数
请你来实现一个 atoi 函数,使其能将字符串转换成整数。
首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。
当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。
该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。
注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。
在任何情况下,若函数不能进行有效的转换时,请返回 0。
说明:
假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。

示例:
输入: "42"
输出: 42

public class MyAiot {
    public int myAtoi(String str) {
        str = str.trim();
        long number = 0;
        boolean flag = false;
        boolean first = true;
        for (int i = 0; i < str.length(); i++) {
            Character c = str.charAt(i);
            if(c == '-' && first == true) {
                flag = true;
                first = false;
                continue;
            } else if (c == '+' && first == true) {
                first = false;
                continue;
            }
            if(c <= '9' && c >= '0') {
                number = number * 10 + (c - 48);
            } else {
                break;
            }
        }
        if(flag == true) {
            number = number * (-1);
            if(number < Integer.MIN_VALUE) {
                return Integer.MIN_VALUE;
            } else {
                return (int)number;
            }
        }
        if(number > Integer.MAX_VALUE) {
            return Integer.MAX_VALUE;
        } else {
            return (int) number;
        }
    }
}

9、回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例:
输入: 121
输出: true

class Solution {
      public static boolean isPalindrome(int x) { 
        int y = x;
        int number = 0;
        int mod = y%10;
        while(y != 0 && y > 0) {
            number = number*10 + mod;
            y = y/10;
            mod = y%10;
        }
        if(x == number) return true;
        return false;
    }
}

10、正则表达式匹配
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '' 的正则表达式匹配。
'.' 匹配任意单个字符
'
' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

示例:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

11、猜数字
小A 和 小B 在玩猜数字。小B 每次从 1, 2, 3 中随机选择一个,小A 每次也从 1, 2, 3 中选择一个猜。他们一共进行三次这个游戏,请返回 小A 猜对了几次?

class Solution {
    public int game(int[] guess, int[] answer) {
        int count = 0;
        for (int i = 0; i < guess.length; i++) {
            if(guess[i] == answer[i]) {
                count++;
            }
        }
        return count;
    }
}

12、机器人大冒险
力扣团队买了一个可编程机器人,机器人初始位置在原点(0, 0)。小伙伴事先给机器人输入一串指令command,机器人就会无限循环这条指令的步骤进行移动。指令有两种:
U: 向y轴正方向移动一格
R: 向x轴正方向移动一格。
不幸的是,在 xy 平面上还有一些障碍物,他们的坐标用obstacles表示。机器人一旦碰到障碍物就会被损毁。
给定终点坐标(x, y),返回机器人能否完好地到达终点。如果能,返回true;否则返回false。

示例:
输入:command = "URR", obstacles = [], x = 3, y = 2
输出:true
解释:U(0, 1) -> R(1, 1) -> R(2, 1) -> U(2, 2) -> R(3, 2)。

public class Robot {
    public static void main(String[] args) {
        System.out.println(robot("URR", new int[][]{{2,2}}, 3,2 ));
    }
    public static boolean robot(String command, int[][] obstacles, int x, int y) {
        int aimx = 0;
        int aimy = 0;
        HashMap<Integer, Integer> map = new HashMap();
        for (int i = 0; i < obstacles.length; i++) {
            map.put(obstacles[i][0], obstacles[i][1]);
        }
        while (true) {
            int i;
            for (i = 0; i < command.length(); i++) {
                  if('U' == command.charAt(i)) {
                      aimy++;
                  } else if('R' == command.charAt(i)) {
                      aimx++;
                  }
                if(map.getOrDefault(aimx, null) != null) {
                    if(map.get(aimx) == aimy) {
                        return false;
                    }
                }
                if(aimx > x || aimy > y) {
                    return false;
                }
                  if(x == aimx && y == aimy) {
                      return true;
                  }
            }
        }
    }
}

13、发 LeetCoin
该刷题团队的管理模式可以用一棵树表示:
团队只有一个负责人,编号为1。除了该负责人外,每个人有且仅有一个领导(负责人没有领导);
不存在循环管理的情况,如A管理B,B管理C,C管理A。
力扣想进行的操作有以下三种:
给团队的一个成员(也可以是负责人)发一定数量的LeetCoin;
给团队的一个成员(也可以是负责人),以及他/她管理的所有人(即他/她的下属、他/她下属的下属,……),发一定数量的LeetCoin;
查询某一个成员(也可以是负责人),以及他/她管理的所有人被发到的LeetCoin之和。
输入:
N表示团队成员的个数(编号为1~N,负责人为1);
leadership是大小为(N - 1) * 2的二维数组,其中每个元素[a, b]代表b是a的下属;
operations是一个长度为Q的二维数组,代表以时间排序的操作,格式如下:
operations[i][0] = 1: 代表第一种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量;
operations[i][0] = 2: 代表第二种操作,operations[i][1]代表成员的编号,operations[i][2]代表LeetCoin的数量;
operations[i][0] = 3: 代表第三种操作,operations[i][1]代表成员的编号;
输出:
返回一个数组,数组里是每次查询的返回值(发LeetCoin的操作不需要任何返回值)。由于发的LeetCoin很多,请把每次查询的结果模1e9+7 (1000000007)。

示例:
输入:N = 6, leadership = [[1, 2], [1, 6], [2, 3], [2, 5], [1, 4]], operations = [[1, 1, 500], [2, 2, 50], [3, 1], [2, 6, 15], [3, 1]]
输出:[650, 665]
解释:团队的管理关系见下图。
第一次查询时,每个成员得到的LeetCoin的数量分别为(按编号顺序):500, 50, 50, 0, 50, 0;
第二次查询时,每个成员得到的LeetCoin的数量分别为(按编号顺序):500, 50, 50, 0, 50, 15.

14、四数相加(454)
给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0。
为了使问题简单化,所有的 A, B, C, D 具有相同的长度 N,且 0 ≤ N ≤ 500 。所有整数的范围在-228 到 228 - 1 之间,最终结果不会超过 231-1 。

例如:
输入:
A = [ 1, 2]
B = [-2,-1]
C = [-1, 2]
D = [ 0, 2]
输出:
2

class Solution {
    public int fourSumCount(int[] A, int[] B, int[] C, int[] D) {
         Map<Integer ,Integer> mapAB =new HashMap<>();
        int res =0;

        for(int i =0 ; i<A.length ;i++){
            for(int j =0 ; j<B.length ;j++){
                int key =A[i]+B[j];
                if(mapAB.containsKey(key))
                    mapAB.put(key,mapAB.get(key)+1);
                else mapAB.put(key,1);
            }
        }

        for(int i =0 ; i<C.length ;i++){
            for(int j =0 ; j<D.length ;j++){
                int key =C[i]+D[j];
                if(mapAB.containsKey(0-key)){
                    res += mapAB.get(0-key);
                }
            }
        }
        return res;
    }
}

15、Fizz Buzz
写一个程序,输出从 1 到 n 数字的字符串表示。

  1. 如果 n 是3的倍数,输出“Fizz”;

  2. 如果 n 是5的倍数,输出“Buzz”;

  3. 如果 n 同时是3和5的倍数,输出 “FizzBuzz”。

    示例:
    n = 15,
    返回:
    [

    "1",
    "2",
    "Fizz",
    "4",
    "Buzz",
    "Fizz",
    "7",
    "8",
    "Fizz",
    "Buzz",
    "11",
    "Fizz",
    "13",
    "14",
    "FizzBuzz"

    ]

    class Solution {
    public static List<String> fizzBuzz(int n) {
          List<String> stringList = new ArrayList<>();
          for (int i = 1; i <= n; i++) {
              if(i%3 == 0 && i%5 == 0) {
                  stringList.add("FizzBuzz");
              } else if(i%5 == 0) {
                  stringList.add("Buzz");
              } else if(i%3 == 0) {
                  stringList.add("Fizz");
              } else {
                  stringList.add(String.valueOf(i));
              }
          }
          return stringList;
      }
    }

    16、至少有K个重复字符的最长子串
    找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k 。输出 T 的长度。

    示例:
    输入:
    s = "aaabb", k = 3
    输出:
    3
    最长子串为 "aaa" ,其中 'a' 重复了 3 次。
    思路:递归拆分子串,分治。先统计出每个字符出现的频次,维护一对双指针,从首尾开始统计,从首尾往中间排除,如果出现次数小于k则不可能出现在最终子串中,排除并挪动指针,然后得到临时子串,依次从头遍历,一旦发现出现频次小于k的字符,以该字符为分割线,分别递归求其最大值返回。

    class Solution {
      public int longestSubstring(String s, int k) {
          int len = s.length();
          if(len == 0 || k > len ) return 0;
          if(k < 2) return len;
          return count(s.toCharArray(), k, 0, len-1);
      }
    
      private int count(char[] chars, int k, int p1, int p2) {
          if(p2-p1+1 < k) return 0;
          int[] times = new int[26];
          for (int i = p1; i <= p2; i++) {
              ++times[chars[i] - 'a'];
          }
          while (p2-p1+1 >= k && times[chars[p1] - 'a'] < k) {
              p1++;
          }
          while (p2-p1+1 >= k && times[chars[p2] - 'a'] < k) {
              p2--;
          }
          if(p2-p1+1 < k) return 0;
          for (int i = p1; i < p2; i++) {
              if(times[chars[i] - 'a'] < k) {
                  return Math.max(count(chars, k, p1, i-1), count(chars, k, i+1, p2));
              }
          }
          return p2-p1+1;
      }
    }

    17、字符串中第一个唯一字符
    给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

    案例:
    s = "leetcode"
    返回 0.
    s = "loveleetcode",
    返回 2.

18、删除排序数组中的重复项
给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。

class Solution {
     public int removeDuplicates(int[] nums) {
          if(nums==null || nums.length == 1){
            return nums.length;
        }
        int i = 0,j =1;
        while(j<nums.length){
            if(nums[i]==nums[j]){
                j++;
            }else{
                i++;
                nums[i]=nums[j];
                j++;
            }
        }
        return i+1;
    }
}

19、每日温度
根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。

class Solution {
    public int[] dailyTemperatures(int[] T) {
        int length = T.length;
        int[] tmp = new int[length];
        for (int i = 0; i < length; i++) {
            for (int j = i+1; j < length; j++) {
                if(T[i] < T[j]) {
                    tmp[i] = j - i;
                    break;
                }
            }
        }
        return tmp;
    }
}

20、罗马数字转整数
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。

21、电话号码的字母组合
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

class Solution {
     public List<String> letterCombinations(String digits) {
        if (digits == null || digits.length() == 0){
            return new ArrayList<>();
        }
        Map<Character, String> map = new HashMap<>();
        map.put('2',"abc");
        map.put('3',"def");
        map.put('4',"ghi");
        map.put('5',"jkl");
        map.put('6',"mno");
        map.put('7',"pqrs");
        map.put('8',"tuv");
        map.put('9',"wxyz");

        List<String> res = new LinkedList<>();
        helper("", digits, 0, res, map);
        return res;

    }

    private void helper(String s, String digits, int i, List<String> res, Map<Character, String> map) {
        if(i == digits.length()) {
            res.add(s);
            return;
        }
        String letters = map.get(digits.charAt(i));
        for (int j = 0; j < letters.length(); j++) {
            helper(s+letters.charAt(j), digits, i+1, res, map);
        }
    }
}

22、全排列 II
给定一个可包含重复数字的序列,返回所有不重复的全排列。

示例:
输入: [1,1,2]
输出: [ [1,1,2],[1,2,1],[2,1,1] ]

class Solution {
    public List<List<Integer>> permuteUnique(int[] nums) {
        List<List<Integer>> result = new ArrayList<>();
         List<Integer> tmp = new ArrayList<>();
         tmp.add(nums[0]);
         result.add(tmp);
         for (int i = 1; i < nums.length; i++) {
             int length = result.size();
             for (int j = 0; j < length; j++) {
                 for (int k = 0; k <= i; k++) { 
                     if(k < i) {
                         List<Integer> temp = new ArrayList<>();
                         temp.addAll(result.get(j));
                         temp.add(k, nums[i]);
                         result.add(temp);
                     } else {
                         List<Integer> temp = result.get(j);
                         if(!result.contains(temp.add(nums[i]))) {
                             result.add(temp);
                         }
                     }
                 }
             }
         }  
         return result;
    }

23、全排序
给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:
输入: [1,2,3]
输出:[ [1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1] ]

class Solution {
    public List<List<Integer>> permute(int[] nums) {
         List<Integer> integers = new ArrayList<>();
        List<List<Integer>> tmp = new ArrayList<>();
        integers.add(nums[0]);
        tmp.add(integers);
        for (int i = 1; i < nums.length; i++) {
            int size = tmp.size();
            for (int k = 0; k < size; k++) {
                List<Integer> elem = tmp.get(k);
                for (int t = 0; t <= i; t++) {
                    if(t < i) {
                        List<Integer> temp = new ArrayList<>();
                        temp.addAll(elem);
                        temp.add(t, nums[i]);
                        tmp.add(temp);
                    } else {
                        tmp.get(k).add(nums[i]);
                    }
                }
            }
        }
        return tmp;
    }
}

24、搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。

示例 1: 输入: [1,3,5,6], 5 输出: 2
示例 2: 输入: [1,3,5,6], 2 输出: 1
示例 3: 输入: [1,3,5,6], 7 输出: 4
示例 4: 输入: [1,3,5,6], 0 输出: 0

class Solution {
    public int searchInsert(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            if(nums[i] == target || nums[i] > target) {
                return i;
            } 
        }
        return nums.length;
    }
}

25、两数相除
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。

示例 1: 输入: dividend = 10, divisor = 3 输出: 3
示例 2: 输入: dividend = 7, divisor = -3 输出: -2
说明:被除数和除数均为 32 位有符号整数。除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。

class Solution {
    public int divide(int dividend, int divisor) {
        if(dividend == Integer.MIN_VALUE && divisor == -1) {
            return Integer.MAX_VALUE;
        }
        return dividend/divisor;
    }
}

26、 二进制求和
给定两个二进制字符串,返回他们的和(用二进制表示)。
输入为非空字符串且只包含数字 1 和 0。

示例 1: 输入: a = "11", b = "1" 输出: "100"
示例 2: 输入: a = "1010", b = "1011" 输出: "10101"

class Solution {
    public String addBinary(String a, String b) {
         StringBuffer stringBuffer = new StringBuffer();
        int i; int j; int mod = 0; int vod = 0;
        for (i = a.length() - 1, j = b.length() - 1; i >= 0 || j >= 0; i--, j--) {
            int x = i >= 0 ? a.charAt(i) - '0' : 0;
            int y = j >= 0 ? b.charAt(j) - '0' : 0;
            int tmp = x + y + vod;
            if(tmp > 1) {
                mod = tmp % 2;
                vod = tmp / 2;
                stringBuffer.append(mod);
            } else {
                vod = 0;
                stringBuffer.append(tmp);
            }
        }
        if(vod == 1) {
            stringBuffer.append(vod);
        }
        return stringBuffer.reverse().toString();
    }
}

27、合并区间
给出一个区间的集合,请合并所有重叠的区间。

示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

class Solution {
    public int[][] merge(int[][] intervals) {
         int count = intervals.length;
        if (count < 2) {
            return intervals;
        }

        Arrays.sort(intervals, (a, b) -> {
            return a[0] - b[0];
        });

        List<int[]> resultList = new ArrayList<int[]>();

        int[] merged = new int[] { intervals[0][0], intervals[0][1] };

        for (int i=1; i<intervals.length; i++) {
             int[] current = intervals[i];
             if (current[0] <= merged[1]) {
                 if (current[1] > merged[1]) {
                    merged[1] = current[1];
                }
            } else {
                resultList.add(merged);
                merged = new int[] { current[0], current[1]};
            }
        }

        resultList.add(merged);

        return resultList.toArray(new int[0][]);
    }
}

28、最大子序和
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:
输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。
进阶: 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。

class Solution {
    public int maxSubArray(int[] nums) {
        int sum;
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < nums.length; i++) {
            sum = 0;
            for (int j = i; j < nums.length; j++) {
                sum += nums[j];
                if(max < sum) {
                    max = sum;
                }
            }
        }
        return max;
    }
}

29、移除元素
给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。

class Solution {
    public int removeElement(int[] nums, int val) {
        int count = 0;
        for (int i = 0; i < nums.length - count;) {
            if(nums[i] == val) {
                count++;
                for (int j = i; j < nums.length - 1; j++) {
                    nums[j] = nums[j+1];
                }
            } else {
                i++;
            }
        }
        return nums.length - count;
    }
}

30、搜索旋转排序数组
假设按照升序排序的数组在预先未知的某个点上进行了旋转。
( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。
搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。
你可以假设数组中不存在重复的元素。
你的算法时间复杂度必须是 O(log n) 级别。

示例 1: 输入: nums = [4,5,6,7,0,1,2], target = 0 输出: 4
示例 2: 输入: nums = [4,5,6,7,0,1,2], target = 3 输出: -1

class Solution {
    public int search(int[] nums, int target) {
          for (int i = 0; i < nums.length; i++) {
            if(nums[i] == target) {
                return i;
            }
        }
        return -1;
    }
}

31、下一个排列
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

class Solution {
    public void nextPermutation(int[] nums) {
          int i;
        for (i = nums.length - 1; i > 0; i--) {
            if(nums[i-1] < nums[i]) break;
        }
        int j;
        if(i != 0) {
            for (j = i; j < nums.length; ++j) {
                if(nums[j] <= nums[i-1]) break;
            }
            int t = nums[i-1];
            nums[i-1] = nums[j-1];
            nums[j-1] = t;
        }
        int t;
        j = nums.length - 1;
        while (i < j) {
            t = nums[j];
            nums[j] = nums[i];
            nums[i] = t;
            ++i;
            --j;
        }
    }
}

32、每日温度
根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数。如果之后都不会升高,请在该位置用 0 来代替。
例如,给定一个列表 temperatures = [73, 74, 75, 71, 69, 72, 76, 73],你的输出应该是 [1, 1, 4, 2, 1, 1, 0, 0]。
提示:气温 列表长度的范围是 [1, 30000]。每个气温的值的均为华氏度,都是在 [30, 100] 范围内的整数。

class Solution {
    public int[] dailyTemperatures(int[] T) {
        int length = T.length;
        int[] tmp = new int[length];
        for (int i = 0; i < length; i++) {
            for (int j = i+1; j < length; j++) {
                if(T[i] < T[j]) {
                    tmp[i] = j - i;
                    break;
                }
            }
        }
        return tmp;
    }
}

33、最短无序连续子数组
给定一个整数数组,你需要寻找一个连续的子数组,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
你找到的子数组应是最短的,请输出它的长度。

示例 1: 输入: [2, 6, 4, 8, 10, 9, 15] 输出: 5
解释: 你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。
说明: 输入的数组长度范围在 [1, 10,000]。输入的数组可能包含重复元素 ,所以升序的意思是<=。

class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int length = nums.length;
        int low = length - 1;
        int high = 0;
        int max = nums[0];
        int min = nums[length-1];
        for (int i = 0;i < length;i++) {
            max = Math.max(nums[i],max);
            min = Math.min(nums[length-i-1],min);
            if (nums[i] < max) {
                high = i;
            }
            if (nums[length-i-1] > min) {
                low = length-i-1;
            }
        }
        if (low >= high) {
            return 0;
        }
        return high-low+1;
    }
}

34、爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。

示例 1:输入: 2 输出: 2
解释: 有两种方法可以爬到楼顶。

  1. 1 阶 + 1 阶
  2. 2 阶
    示例 2:输入: 3 输出: 3
    解释: 有三种方法可以爬到楼顶。
  3. 1 阶 + 1 阶 + 1 阶
  4. 1 阶 + 2 阶
  5. 2 阶 + 1 阶
class Solution {
    public int climbStairs(int n) {
        if (n == 1) {
            return 1;
        }
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

35、字母异位词分组
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。

示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:所有输入均为小写字母。不考虑答案输出的顺序。

class Solution {
    public List<List<String>> groupAnagrams(String[] strs) {
           if(strs.length == 0) return new ArrayList<>();
        Map<String, List> ans = new HashMap<String, List>();
        for (String s : strs) {
            char[] ca = s.toCharArray();
            Arrays.sort(ca);
            String key = String.valueOf(ca);
            if(!ans.containsKey(key)) ans.put(key, new ArrayList());
            ans.get(key).add(s);
        }
        return new ArrayList(ans.values());
    }
}

36、二叉树中序遍历
给定一个二叉树,返回它的中序 遍历。

示例:
输入: [1,null,2,3]
输出: [1,3,2]

class Solution {
       public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<>();
        helper(root, res);
        return res;
    }

    private void helper(TreeNode root, List<Integer> res) {
        if (root != null) {
            if (root.left != null) {
                helper(root.left, res);
            }
            res.add(root.val);
            if (root.right != null) {
                helper(root.right, res);
            }
        }
    }
}