要开始刷题了!请一定要坚持下去哦
- 两数之和
给定一个整数数组 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 数字的字符串表示。
如果 n 是3的倍数,输出“Fizz”;
如果 n 是5的倍数,输出“Buzz”;
如果 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 阶
- 2 阶
示例 2:输入: 3 输出: 3
解释: 有三种方法可以爬到楼顶。- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 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);
}
}
}
}
京公网安备 11010502036488号