【第一题】括号生成
分析:
class Solution {
List<String> res = new ArrayList<>();
public List<String> generateParenthesis(int n) {
if(n <= 0){
return res;
}
getParenthesis("",n,n);
return res;
}
private void getParenthesis(String str,int left, int right) {
if(left == 0 && right == 0 ){
res.add(str);
return;
}
if(left == right){
//剩余左右括号数相等,下一个只能用左括号
getParenthesis(str+"(",left-1,right);
}else if(left < right){
//剩余左括号小于右括号,下一个可以用左括号也可以用右括号
if(left > 0){
getParenthesis(str+"(",left-1,right);
}
getParenthesis(str+")",left,right-1);
}
}
}
class Solution {
public List<List<Integer>> combinationSum3(int k, int n) {
List<List<Integer>> list = new ArrayList<>();
if(n == 0){return list;}
boolean[] used = new boolean[9];
int[] nums = {1,2,3,4,5,6,7,8,9};
dfs(k,n,list,new ArrayList<Integer>(),used,nums);
return list;
}
private void dfs(int k,int n,List<List<Integer>> list,ArrayList<Integer> tmp,boolean[] used,int[] nums){
if(n <=0){
if(n == 0){
list.add(new ArrayList(tmp));
}
return;
}
for(int i = 0;i < nums.length;i++){
if(!used[i]){
if(i > 0 && used[i]==used[i-1] && !used[i-1]){
continue;
}else{
tmp.add(i);
used[i] = true;
dfs(k-1,n-nums[i],list,tmp,used,nums);
used[i] = false;
tmp.remove(tmp.size()-1);
n+=nums[i];
}
}
}
}
}
【第二题】跳台阶
/*分析:两种情况
1、假如第一步跳一个台阶,那么剩下的n-1个台阶跳法是f(n-1)
2、假如第一步跳两个台阶,那么剩下的n-2个台阶跳法是f(n-2)
3、综合以上,跳n个台阶的跳法是:f(n) = f(n-1) + f(n-2)
*/
public class Solution {
public int jumpFloor(int target) {
if(target == 1){return 1;}
else if(target == 2){return 2;}
else{return jumpFloor(target-1) + jumpFloor(target-2);}
}
}
【第三题】矩阵的最小路径和
public class Solution {
/**
*
* @param matrix int整型二维数组 the matrix
* @return int整型
*/
//其实动态规划就是存储到达一个节点时的路径的值,然后选最优
//这里还得判断边界条件
public int minPathSum (int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m][n];
dp[0][0] = matrix[0][0];
//先把第一行填满
for(int i = 1;i < n;i++){
dp[0][i] = dp[0][i-1]+matrix[0][i];
}
//把第一列填满
for(int i = 1;i < m;i++){
dp[i][0] = dp[i-1][0]+matrix[i][0];
}
//将其他填满
for(int i = 1;i < m;i++){
for(int j = 1;j < n;j++){
dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1])+matrix[i][j];
}
}
return dp[m-1][n-1];
}
}
【第四题】有重复元素的二分
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 如果目标值存在返回下标,否则返回 -1
* @param nums int整型一维数组
* @param target int整型
* @return int整型
*/
public int search (int[] nums, int target) {
if(nums.length == 0 || nums == null){return -1;}
int left = 0,right = nums.length;
int mid = left + (right-left) >> 2;
//这里的条件是<=
while(left <= mid){
if(nums[mid] > target){
right = mid-1;
}else if(nums[mid] < target){
left = mid+1;
}else{
//记录下这个索引,假如在该索引之前没有找到target,就返回这个index
index = mid;
high = mid-1;
}
}
return index;
}
}
【第五题】最长公共子串
【第六题】大数相加
class Solution {
public String addStrings(String num1, String num2) {
//一个变长数组
StringBuffer sb = new StringBuffer();
//指向字符串1的指针,指向字符串2的指针,进位标志位carry
int i = num1.length()-1,j = num2.length()-1,carry = 0;
while(i >=0 || j >=0 || carry !=0){
//短的字符串补零
int x = i >=0 ?num1.charAt(i) - '0':0;
int y = j >=0 ?num2.charAt(j) - '0':0;
int result = x + y + carry;
sb.append(result % 10);
carry = result / 10;
i--;
j--;
}
return sb.reverse().toString();
}
}
【第七题】链表中的节点每K个一组翻转
不足K个保持原样。
public class Solution {
public static ListNode reverseKGroup(ListNode head, int k) {
if(head == null || head.next == null || k < 2) return head;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy, cur = head, temp;
int len = 0;
while (head != null) {
len ++ ;
head = head.next;
}
for (int i = 0; i < len / k; i ++ ) {
for (int j = 1; j < k; j ++ ) {
temp = cur.next;
cur.next = temp.next;
temp.next = pre.next;
pre.next = temp;
}
pre = cur;
cur = cur.next;
}
return dummy.next;
}
}