【剑指offer+高频题】随机刷(4.12-4.18)

【第一题】括号生成

在这里插入图片描述

分析:

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个保持原样。
在这里插入图片描述

参考链接:Java 链表中节点每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;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值