0
点赞
收藏
分享

微信扫一扫

剑指Offer(二)

前端王祖蓝 2022-04-29 阅读 41
算法

文章目录

剑指 Offer 10- I. 斐波那契数列

https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/

	/*
	 * 1. 递归,超时
	 * 24 / 51 个通过测试用例,超时
	 */
	public int fib(int n) {
		if(n <= 1) return n;
		return fib(n-1)+fib(n-2);
	}
	
	/*
	 * 2. 动态规划
	 * 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:38.4 MB, 在所有 Java 提交中击败了12.66%的用户
	 */	
	public int fib1(int n) {
		if(n <= 1) return n;
		int[] res = new int[n+1];
		res[0] = 0;
		res[1] = 1;
		int m = 1000000007;
		for(int i=2; i<=n; i++){
			res[i] = (res[i-1] + res[i-2])%m;
		}
		return res[n];
	}
	
	/*
	 * 3.动规优化,只存三个数,节省空间
	 * 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:38 MB, 在所有 Java 提交中击败了64.77%的用户
	 */
	public int fib2(int n) {
		int a = 0, b = 1, sum;
        for(int i = 0; i < n; i++){
            sum = (a + b) % 1000000007;
            a = b;
            b = sum;
        }
        return a;
	}

剑指 Offer 10- II. 青蛙跳台阶问题

https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/

	/*
	 * 1.动规
	 * 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:38 MB, 在所有 Java 提交中击败了63.83%的用户
	 */
	public int numWays(int n) {
		if(n <= 1) return n;
		int[] res = new int[n+1];
		res[0] = 1;
		res[1] = 1;
		int m = 1000000007;
		for(int i=2; i<=n; i++){
			res[i] = (res[i-1] + res[i-2])%m;
		}
		return res[n];
	}

剑指 Offer 11. 旋转数组的最小数字

https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/

	public int minArray(int[] numbers) {
		int res = numbers[0];
		for(int i=1; i<numbers.length; i++){
			if(numbers[i] < numbers[i-1]){
				res = numbers[i];
			}
		}
		return res;
	}

剑指 Offer 12. 矩阵中的路径

https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/
回溯+剪枝

	public boolean exist(char[][] board, String word) {
		char[] words = word.toCharArray();
		for(int i=0; i<board.length; i++){
			for(int j=0; j<board[0].length; j++){
				if(dfs(board, words, i, j, 0)) return true;
			}
		}	
		return false;
	}
	 boolean dfs(char[][] board, char[] words, int i, int j, int k){
		 //越界,不相等,直接false
		 if(i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != words[k]) return false;
		 //已经找到最后一个了,返回true
		 if(k == words.length - 1) return true;
		 //当前字符先标记为空证明访问过
		 board[i][j] = '\0';
		 //上下左右找一下
		 boolean res = dfs(board, words, i+1, j, k + 1) || dfs(board, words, i-1, j, k + 1) || 
				 		dfs(board, words, i, j + 1, k + 1) || dfs(board, words, i , j - 1, k + 1);
		 //恢复原来位置的字符
		 board[i][j] = words[k];
		 return res;
	 }

剑指 Offer 13. 机器人的运动范围

https://leetcode-cn.com/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/

	/*
	 * 1.边界判断注意
	 */
	public int movingCount(int m, int n, int k) {
		if(k == 0) return 1;
		boolean[][] vis = new boolean[m][n];
		vis[0][0] = true;
		show(vis);
		int res = 1;
		for(int i=0; i<m; i++){
			for(int j=0; j<n; j++){
				//1.起始点和超过的不算
				if( i==0 && j==0 || get(i)+get(j) > k) continue;
				//2.单独处理第一行和第一列
				// 边界判断
                if (i - 1 >= 0) {
                    vis[i][j] |= vis[i - 1][j];
                }
                if (j - 1 >= 0) {
                    vis[i][j] |= vis[i][j - 1];
                }
                res += vis[i][j] ? 1 : 0;
				show(vis);
			}
		}
		return res;
	}
	
	int get(int num){
		int res = 0;
		while(num != 0){
			res += num%10;
			num/=10;
		}
		return res;
	}

剑指 Offer 14- I. 剪绳子

数学推导,越多三越大。其实是越多e(2.7…)越大。

	public int cuttingRope(int n) {
        if(n == 2) return 1;
		if(n == 3) return 2;
		
		int res = 0;
		int m = n%3;
		//System.out.println(m);
		if(m == 0){
			res = (int) Math.pow(3, (n/3));
		}else if(m == 1){
			res = (int) Math.pow(3, (n/3)-1)*4;
		}else{
			res = (int) Math.pow(3, (n/3))*2;
		}	
		return res;
    }

剑指 Offer 14- II. 剪绳子 II

https://leetcode-cn.com/problems/jian-sheng-zi-ii-lcof/
快速幂!!快速幂!!快速幂!!快速幂!!快速幂!!快速幂!!

	public int cuttingRope(int n) {
		if(n <= 3) return n - 1;
        int b = n % 3, p = 1000000007;
        long rem = 1, x = 3;
        for(int a = n / 3 - 1; a > 0; a /= 2) {
            if(a % 2 == 1) rem = (rem * x) % p;
            x = (x * x) % p;
        }
        if(b == 0) return (int)(rem * 3 % p);
        if(b == 1) return (int)(rem * 4 % p);
        return (int)(rem * 6 % p);
	}

剑指 Offer 15. 二进制中1的个数

https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/

	/*
	 * 3.
	 * 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:38.7 MB, 在所有 Java 提交中击败了19.64%的用户
	 */
	public int hammingWeight2(int n) {
        int ret = 0;
        while (n != 0) {
            n &= n - 1;
            ret++;
        }
        return ret;
    }
	
	/*
	 * 2. 
	 * 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
	 * 内存消耗:38.8 MB, 在所有 Java 提交中击败了6.87%的用户
	 */
	public int hammingWeight1(int n) {
        int ret = 0;
        for (int i = 0; i < 32; i++) {
            if ((n & (1 << i)) != 0) {
                ret++;
            }
        }
        return ret;
    }
	
	// 方法一:为什么不对呢?
	// 11111111111111111111111111111101 输出30 预期31
	public int hammingWeight(int n) {
		int res = 0;
		while(n != 0){
			if(n%2 == 1) res ++;
			// n/=2;
			n >>>= 1;
		}
		return res;
	}

剑指 Offer 16. 数值的整数次方

https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/submissions/

	/*
	 * 方法2
	 * 快速幂!!
	 */
	public double myPow2(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);
        return N % 2 == 0 ? y * y : y * y * x;
    }
	
	/*
	 * 方法1
	 * 注意n有正负的区分
	 * 第一次超出时间限制,修改x等于1时的判断
	 * 第二次n = -2147483648,这个时候他变成负数还是-2147483648。越界。加入一个坏蛋。
	 * 第三次加入一个坏蛋,顺序错了,应该先判断x是不是正负1
	 * 
	 * 好歹算拿下!
	 * 执行用时:2766 ms, 在所有 Java 提交中击败了6.67%的用户
	 * 内存消耗:40.7 MB, 在所有 Java 提交中击败了35.15%的用户
	 */
	public double myPow(double x, int n) {	
		if(x == 1.00) return 1.00;
		if(x == -1.00){
			if(n%2 == 1){
				return -1.00;
			}else{
				return 1.00;
			}
		}
		if(n == -2147483648) return 0;//一个坏蛋
		
		double res = 1;
		
		if(n < 0){
			x = 1/x; 
			n = -n;
		}
		
		while(n-->0){
			res *= x;
			System.out.println(res);
		}
		
		return res;
	}

剑指 Offer 17. 打印从1到最大的n位数

https://leetcode-cn.com/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/

public int[] printNumbers(int n) {
		int maxNum = (int)Math.pow(10, n);
		int[] res = new int[maxNum-1];
		for(int i=0; i<maxNum-1; i++){
			res[i] = i+1;
		}
		return res;
	}

剑指 Offer 18. 删除链表的节点

https://leetcode-cn.com/problems/shan-chu-lian-biao-de-jie-dian-lcof/

	public ListNode deleteNode(ListNode head, int val) {
		if(head == null) return null;
		if(head.val == val) return head.next;
		ListNode cur = head;
		while(cur.next != null && cur.next.val != val) {
			cur = cur.next;
		}
		if(cur.next != null){
			cur.next = cur.next.next;
		}
		return head;
	}
举报

相关推荐

0 条评论