文章目录
040.括号生成【中】
题意: 生成给定数目的括号
分析: 括号的数目确定
解法:
class Solution {
List<String> ans = new ArrayList<>();
public List<String> generateParenthesis(int n) {
_generate(n, n, n, "");
return ans;
}
private void _generate(int left, int right, int n, String s) {
if (left == 0 && right == 0) {
ans.add(s);
return;
}
if (left > 0) {
_generate(left - 1, right, n, s + "(");
}
if (left < right) {
_generate(left, right - 1, n, s + ")");
}
}
}
041.存在重复元素【简】
题意: 判断数组中是否存在重复元素
分析: 可以一开始就给数组进行排序,时间复杂度为 O ( n l o g ( n ) ) O(nlog(n)) O(nlog(n))
也可以使用hash表,直接看看是否重复即可。
解法: hash O ( n ) O(n) O(n)
class Solution {
public boolean containsDuplicate(int[] nums) {
Set set = new HashSet();
for(int i=0;i<nums.length;i++){
if(!set.add(nums[i])){
return true;
}
}
return false;
}
}
042.最大子数组和【中】
题意: 寻找数组中连续的和最大的子数组
分析: 如果前面和小于0,那么就不加入前面的
解题: O ( n ) O(n) O(n)
class Solution {
public int maxSubArray(int[] nums) {
int ans = nums[0],tmp = 0;
for(int i = 0; i<nums.length; i++){
if(tmp>0){
tmp += nums[i];
}else{
tmp=nums[i];
}
if(tmp>ans)ans=tmp;
}
return ans;
}
}
043.验证二叉搜索树【中】
题意: 判断是否为二叉搜索树
分析: 要注意左子树始终小于右子树
解法: 递归
class Solution {
public boolean isValidBST(TreeNode root) {
return validate(root, Long.MIN_VALUE, Long.MAX_VALUE);
}
public boolean validate(TreeNode node, long min, long max) {
if (node == null) {
return true;
}
if (node.val <= min || node.val >= max) {
return false;
}
return validate(node.left, min, node.val) && validate(node.right, node.val, max);
}
}
044.pow(x,n) 【中】🎈
题意: 计算x的n次方
分析: 分治计算一半,另一半也就求出来了
解法: 分治 O ( l o g n ) O(logn) O(logn)
class Solution {
public double getPow(double x,long n) {
if (n == 0)
return 1.0;
double ans = getPow(x, n / 2);
if (n % 2 == 1)
return ans * ans * x;
return ans * ans;
}
public double myPow(double x, int n) {
long N =n;
return N>=0?getPow(x,N):1.0/getPow(x,-N);
}
}
045.子集【中】💡
题意: 寻找一个数组的所有子集
分析: 递归,可以加也可以不加,得到所有情况。
解法①: 递归dfs O ( n ∗ 2 n ) O(n*2^n) O(n∗2n)
可以加也可以不加,得到所有情况
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
dfs(ans, new ArrayList<Integer>(), nums, 0);
return ans;
}
private void dfs(List<List<Integer>> ans, List<Integer> list, int[] nums, int index) {
if (index == nums.length) {
ans.add(new ArrayList<>(list));
return;
}
dfs(ans, list, nums, index + 1);
list.add(nums[index]);
dfs(ans, list, nums, index + 1);
list.remove(list.size() - 1);
}
}
解法②: 迭代 O ( n ∗ 2 n ) O(n*2^n) O(n∗2n)
每向后移动,遍历一下所有的结果集,得到加入此数字后集合的值。
class Solution {
public List<List<Integer>> subsets(int[] nums) {
List<List<Integer>> ans = new ArrayList<>();
ans.add(new ArrayList<>());
for (int num : nums) {
int n = ans.size();
for (int i = 0; i < n; i++) {
List<Integer> tmp = new ArrayList<>(ans.get(i));
tmp.add(num);
ans.add(tmp);
}
}
return ans;
}
}
046.多数元素【简】🎈
题意: 寻找数组中占据一半以上的元素
分析: 如何确定最多的元素?
解法①: 摩尔投票法 O ( n ) O(n) O(n)
多数元素与其它元素一比一消耗,剩下的就是多数元素
class Solution {
public int majorityElement(int[] nums) {
int ans = nums[0], count = 1;
for (int i = 1; i < nums.length; i++) {
if (count == 0) {
ans = nums[i];
count++;
} else {
count = (ans == nums[i]) ? count + 1 : count - 1;
}
}
return ans;
}
}
047.电话号码的字母组合【中】
题意: 9键打字,输入数字,输出可能的字母组合
分析: 几层递归即可
解法:
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> list = new LinkedList<>();
getStr("", 0, list, digits, map);
return list;
}
private void getStr(String str, int i, List<String> list, String digits, Map<Character, String> map) {
if (i == digits.length()) {
list.add(str);
return;
}
String letter = map.get(digits.charAt(i));
for (int j = 0; j < letter.length(); j++) {
getStr(str + letter.charAt(j), i + 1, list, digits, map);
}
}
}
048.n皇后【难】🚩
题意: n皇后
分析: 不能横竖斜
解题: 回溯 O ( n ! ) O(n!) O(n!)
class Solution {
public List<List<String>> solveNQueens(int n) {
List<List<String>> solutions = new ArrayList<>();
int[] queens = new int[n];
Arrays.fill(queens, -1);
Set<Integer> columns = new HashSet<>();
Set<Integer> xie1 = new HashSet<>();
Set<Integer> xie2 = new HashSet<>();
getQueen(solutions, queens, n, 0, columns, xie1, xie2);
return solutions;
}
private void getQueen(List<List<String>> solutions, int[] queens, int n, int row, Set<Integer> columns,
Set<Integer> xie1, Set<Integer> xie2) {
if (row == n) {
List<String> board = generateBoard(queens, n);
solutions.add(board);
} else {
for (int i = 0; i < n; i++) {
if (columns.contains(i)) {
continue;
}
if (xie1.contains(row - i))
continue;
if (xie2.contains(row + i))
continue;
queens[row] = i;
columns.add(i);
xie1.add(row - i);
xie2.add(row + i);
getQueen(solutions, queens, n, row + 1, columns, xie1, xie2);
queens[row] = -1;
columns.remove(i);
xie1.remove(row - i);
xie2.remove(row + i);
}
}
}
private List<String> generateBoard(int[] queens, int n) {
List<String> board = new ArrayList<>();
for (int i = 0; i < n; i++) {
char[] row = new char[n];
Arrays.fill(row, '.');
row[queens[i]] = 'Q';
board.add(new String(row));
}
return board;
}
}
049.二叉树的层序遍历【中】
分析: 层序输出二叉树,相同层次要放到一个数组中
只是简单的层序遍历,不同层次的遍历有两种处理方法,一是新建queue,然后遍历,一是记录queue的size,然后遍历
解法: BFS O ( n ) O(n) O(n)
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new ArrayDeque<>();
Queue<TreeNode> tmp = new ArrayDeque<>();
if (root == null)
return new ArrayList<>();
queue.add(root);
List<List<Integer>> ans = new ArrayList<>();
while (!queue.isEmpty()) {
tmp = queue;
queue = new ArrayDeque<>();
List<Integer> list = new ArrayList<>();
while (!tmp.isEmpty()) {
TreeNode node = tmp.poll();
list.add(node.val);
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
ans.add(list);
}
return ans;
}
}