LeetCode第41题
缺失的第一个正数
class Solution {
public int firstMissingPositive(int[] nums) {
int n=nums.length;
for (int i=0;i<n;i++){
if (nums[i]<=0){
nums[i]=n+1;
}
}
for (int i=0;i<n;i++){
int num = Math.abs(nums[i]);
if (num <= n) {
nums[num - 1] = -Math.abs(nums[num - 1]);
}
}
for (int i=0;i<n;i++){
if (nums[i]>0){
return i+1;
}
}
return n+1;
}
}
LeetCode第42题
接雨水
暴力法:
class Solution {
public int trap(int[] height) {
int ans = 0;
int size = height.length;
for (int i = 1; i < size - 1; i++) {
int max_left = 0, max_right = 0;
for (int j = i; j >= 0; j--) { //Search the left part for max bar size
max_left = Math.max(max_left, height[j]);
}
for (int j = i; j < size; j++) { //Search the right part for max bar size
max_right = Math.max(max_right, height[j]);
}
ans += Math.min(max_left, max_right) - height[i];
}
return ans;
}
}
动态编程法:
class Solution {
public int trap(int[] height) {
int[] left=new int[height.length];
int[] right=new int[height.length];
Stack<Integer> stack=new Stack<>();
int max=0;
for (int i=0;i<height.length;i++){
if (height[i]>height[max]){
max=i;
}
left[i]=max;
}
max= height.length-1;
for (int i=height.length-1;i>=0;i--){
if (height[i]>height[max]){
max=i;
}
right[i]=max;
}
int total=0;
for (int i=0;i<height.length;i++){
int h=Math.min(height[right[i]],height[left[i]]);
total+=h-height[i];
}
return total;
}
}
LeetCode第43题
字符串相乘
class Solution {
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
// 保存计算结果
String res = "0";
for (int i=num2.length()-1;i>=0;i--){
int x=num2.charAt(i)-'0';
int add=0;
StringBuilder temp = new StringBuilder();
for (int j=num2.length()-1;j>i;j--){
System.out.println("asdasd");
temp.append(0);
}
for (int j=num1.length()-1;j>=0||add!=0;j--){
int y=0;
if (j>=0)
y=num1.charAt(j)-'0';
int result=x*y+add;
temp.append(result%10);
add=result/10;
}
res=addStrings(res,temp.reverse().toString());
}
return res;
}
public String addStrings(String num1, String num2) {
int x=num1.length()-1;
int y=num2.length()-1;
StringBuilder sb=new StringBuilder();
int add=0;
while (x>=0||y>=0||add!=0){
int xx=0,yy=0;
if (x>=0){
xx=num1.charAt(x)-'0';
}
if (y>=0){
yy=num2.charAt(y)-'0';
}
int result=xx+yy+add;
sb.append(result%10);
add=result/10;
x--;y--;
}
sb.reverse();
return sb.toString();
}
}
LeetCode第44题
通配符匹配:动态规划
class Solution {
public boolean isMatch(String s, String p) {
boolean[][] dp=new boolean[s.length()+1][p.length()+1];
dp[0][0]=true;
for (int i=1;i<dp[0].length;i++){
if (p.charAt(i-1)=='*'){
dp[0][i]=dp[0][i-1];
}
}
for (int i=1;i<dp.length;i++){
char schar=s.charAt(i-1);
for (int j=1;j<dp[0].length;j++){
char pchar=p.charAt(j-1);
if (schar==pchar||pchar=='?'){
dp[i][j]=dp[i-1][j-1];
}else if (pchar=='*'){
dp[i][j]=dp[i-1][j]==true?dp[i-1][j]:dp[i][j-1];
}
}
}
return dp[s.length()][p.length()];
}
}
LeetCode第45题
跳跃游戏 II:贪心算法
class Solution {
public int jump(int[] nums) {
int index=0;
int count=0;
while (index<nums.length-1){
int x=nums[index];
int min=1;
for (int i=1;i<=x;i++){
if (index+i>=nums.length-1){
return count+1;
}
if (i+nums[index+i]>=nums[index+min]+min){
min=i;
}
}
index+=min;
count++;
}
return count;
}
}
LeetCode第46题
全排列:回溯法
class Solution {
private List<List<Integer>> result=new ArrayList<>();
public List<List<Integer>> permute(int[] nums) {
boolean flag[]=new boolean[nums.length];
List<Integer> tmp=new ArrayList<>();
dfs(nums,0,flag,tmp);
return result;
}
public void dfs(int[] nums,int count,boolean[] flag,List<Integer> temp){
if (count==nums.length){
result.add(new ArrayList<>(temp));
return;
}
for (int i=0;i<nums.length;i++){
if (!flag[i]){
temp.add(nums[i]);
flag[i]=true;
dfs(nums,count+1,flag,temp);
temp.remove(count);
flag[i]=false;
}
}
}
}
LeetCode第47题
全排列2:回溯法加剪枝条件
class Solution {
private List<List<Integer>> result=new ArrayList<>();
public List<List<Integer>> permuteUnique(int[] nums) {
Arrays.sort(nums);
boolean flag[]=new boolean[nums.length];
List<Integer> tmp=new ArrayList<>();
dfs(nums,0,flag,tmp);
return result;
}
public void dfs(int[] nums,int count,boolean[] flag,List<Integer> temp){
if (count==nums.length){
result.add(new ArrayList<>(temp));
return;
}
for (int i=0;i<nums.length;i++){
if (flag[i]){
continue;
}
if(i>0 && nums[i] == nums[i-1] && flag[i-1]) break;
temp.add(nums[i]);
flag[i]=true;
dfs(nums,count+1,flag,temp);
temp.remove(count);
flag[i]=false;
}
}
}
LeetCode第48题
旋转图像:方法就是四角交换
class Solution {
public void rotate(int[][] matrix) {
boolean[][] flag=new boolean[matrix.length][matrix[0].length];
for (int i=0;i<matrix.length;i++){
for (int j=0;j<matrix[i].length;j++){
int tmp=matrix[i][j];
int x=i,y=j;
int count=0;
while (!flag[x][y]){
if (count!=3){
matrix[x][y]=matrix[matrix.length-y-1][x];
}else {
matrix[x][y]=tmp;
}
count++;
flag[x][y]=true;
int change=x;
x=matrix.length-y-1;
y=change;
}
}
}
}
}
LeetCode第49题
字母异位词分词
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String,List<String>> map=new HashMap<>();
for (int i=0;i<strs.length;i++){
char ch[]=strs[i].toCharArray();
Arrays.sort(ch);
String key=new String(ch);
if (!map.containsKey(key)){
List<String> l=new ArrayList<>();
l.add(strs[i]);
map.put(key,l);
}else {
map.get(key).add(strs[i]);
}
}
return new ArrayList<>(map.values());
}
}
LeetCode第50题
Pow(x,y):分治算法
class Solution {
public double myPow(double x, int n) {
long N=n;
return N>0?quickMul(x,N):1.0/quickMul(x,N);
}
public double quickMul(double x, long n) {
if (n==0){
return 1.0;
}
double y=quickMul(x,n/2);
if (n%2==0){
return y*y;
}else{
return y*y*x;
}
}
}
LeetCode第51题
n皇后(返回解决方案):回溯法
class Solution {
private List<List<String>> result=new ArrayList<>();
public List<List<String>> solveNQueens(int n) {
char[][] chars=new char[n][n];
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
chars[i][j]='.';
}
}
boolean col[]=new boolean[n];
List<String> slist=new ArrayList<>();
dfs(0,col,chars,slist);
return result;
}
public void dfs(int row,boolean[] col,char[][] chars,List<String> slist){
if (row==chars.length){
result.add(new ArrayList<String>(slist));
return;
}
for (int i=0;i<chars.length;i++){
if (!col[i]&&valid(row,i,chars)){
chars[row][i]='Q';
col[i]=true;
slist.add(new String(chars[row]));
dfs(row+1,col,chars,slist);
slist.remove(slist.size()-1);
col[i]=false;
chars[row][i]='.';
}
}
}
public boolean valid(int row,int col,char[][] chars){
for (int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
if (chars[i][j]=='Q'){
return false;
}
}
for (int i=row-1,j=col+1;i>=0&&j<chars.length;i--,j++){
if (chars[i][j]=='Q'){
return false;
}
}
return true;
}
}
LeetCode第52题
n皇后(返回解决个数):回溯法,同51题
class Solution {
private int num=0;
public int totalNQueens(int n) {
char[][] chars=new char[n][n];
for (int i=0;i<n;i++){
for (int j=0;j<n;j++){
chars[i][j]='.';
}
}
boolean col[]=new boolean[n];
dfs(0,col,chars);
return num;
}
public void dfs(int row,boolean[] col,char[][] chars){
if (row==chars.length){
num++;
return;
}
for (int i=0;i<chars.length;i++){
if (!col[i]&&valid(row,i,chars)){
chars[row][i]='Q';
col[i]=true;
dfs(row+1,col,chars);
col[i]=false;
chars[row][i]='.';
}
}
}
public boolean valid(int row,int col,char[][] chars){
for (int i=row-1,j=col-1;i>=0&&j>=0;i--,j--){
if (chars[i][j]=='Q'){
return false;
}
}
for (int i=row-1,j=col+1;i>=0&&j<chars.length;i--,j++){
if (chars[i][j]=='Q'){
return false;
}
}
return true;
}
}
LeetCode第53题
最大子序和:动态规划,dp用来存储以当前字母结尾的最大子序和
class Solution {
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
dp[0] = nums[0];
int max = nums[0];
for (int i = 1; i < nums.length; i++) {
dp[i] = Math.max(dp[i- 1] + nums[i], nums[i]);
if (max < dp[i]) {
max = dp[i];
}
}
return max;
}
}
LeetCode第54题
螺旋矩阵
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> result=new ArrayList<Integer>();
if (matrix.length==0){
return result;
}
int i=0,j=0;
int all=matrix.length*matrix[0].length;
int count=0;
boolean row=true;
boolean right=true;
boolean[][] flag=new boolean[matrix.length][matrix[0].length];
boolean down=false;
while (count<all){
result.add(matrix[i][j]);
flag[i][j]=true;
if (row){
if (right){
if (j==matrix[0].length-1||flag[i][j+1]){
down=true;
row=false;
i++;
}else {
j++;
}
}else {
if (j==0||flag[i][j-1]){
down=false;
row=false;
i--;
}else {
j--;
}
}
}else {
if (down){
if (i==matrix.length-1||flag[i+1][j]){
row=true;
right=false;
j--;
}else {
i++;
}
}else {
if (flag[i-1][j]){
row=true;
right=true;
j++;
}else {
i--;
}
}
}
count++;
}
return result;
}
}
LeetCode第55题
跳跃游戏:如果已经确定能到达的最大位置没有当前位置远,那么会失败
class Solution {
public boolean canJump(int[] nums){
int k=0;
for (int i=0;i<nums.length;i++){
if (k<i){
return false;
}
k=Math.max(i+nums[i],k);
}
return true;
}
}
LeetCode第56题
合并区间
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, Comparator.comparingInt(v -> v[0]));
int[][] res = new int[intervals.length][2];
int index=0;
for (int[] interval:intervals){
if (index==0||interval[0]>res[index-1][1]){
res[index++]=interval;
}else {
res[index-1][1]=Math.max(res[index-1][1],interval[1]);
}
}
return Arrays.copyOf(res, index);
}
}
LeetCode第57题
插入区间
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
int[][] oldIntervals = Arrays.copyOf(intervals, intervals.length + 1);
oldIntervals[oldIntervals.length-1]=newInterval;
Arrays.sort(oldIntervals, Comparator.comparingInt(v -> v[0]));
int[][] res = new int[oldIntervals.length][2];
int index=0;
for (int[] interval:oldIntervals){
if (index==0||interval[0]>res[index-1][1]){
res[index++]=interval;
}else {
res[index-1][1]=Math.max(res[index-1][1],interval[1]);
}
}
return Arrays.copyOf(res, index);
}
}
LeetCode第58题
最后一个单词的长度
class Solution {
public int lengthOfLastWord(String s) {
int start=-1,end=-1;
boolean flag=false;
for (int i=s.length()-1;i>=0;i--){
char ch=s.charAt(i);
if (ch==' '){
if (flag){
start=i+1;
return end-start+1;
}
}else {
if (!flag){
flag=true;
end=i;
}
}
}
if (!flag){
return 0;
}
start=0;
return end-start+1;
}
}
LeetCode第59题
螺旋矩阵2
class Solution {
public int[][] generateMatrix(int n) {
int[][] matrix=new int[n][n];
boolean[][] flag=new boolean[n][n];
int i=0,j=0;
int all=matrix.length*matrix[0].length;
int count=0;
boolean row=true;
boolean right=true;
boolean down=false;
while (count<all){
matrix[i][j]=count+1;
flag[i][j]=true;
if (row){
if (right){
if (j==matrix[0].length-1||flag[i][j+1]){
down=true;
row=false;
i++;
}else {
j++;
}
}else {
if (j==0||flag[i][j-1]){
down=false;
row=false;
i--;
}else {
j--;
}
}
}else {
if (down){
if (i==matrix.length-1||flag[i+1][j]){
row=true;
right=false;
j--;
}else {
i++;
}
}else {
if (flag[i-1][j]){
row=true;
right=true;
j++;
}else {
i--;
}
}
}
count++;
}
return matrix;
}
}
LeetCode第60题
第k个排列:官方的方法看不懂,用回溯法解决效率感人
class Solution {
StringBuilder sb=new StringBuilder();
public int num=0;
boolean flag=false;
String re="";
public String getPermutation(int n, int k) {
boolean[] visited=new boolean[n];
dfs(n,k,0,visited);
return re;
}
public void dfs(int n,int k,int length,boolean[] visited){
if (length==n){
num++;
if (num==k){
flag=true;
re=sb.toString();
return;
}
}
for (int i=1;i<=n;i++){
if (!flag){
if (!visited[i-1]){
visited[i-1]=true;
sb.append(i);
dfs(n,k,length+1,visited);
sb.deleteCharAt(length);
visited[i-1]=false;
}
}else {
break;
}
}
}
}