LeetCode41~60题——NWU_LK

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;
            }

        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值