Notes4剑指offer_03-20题

Posted 码农编程录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Notes4剑指offer_03-20题相关的知识,希望对你有一定的参考价值。


3.数组中重复的数字

题目链接:https://leetcode-cn.com/problemset/lcof/

class Solution {
    public int findRepeatNumber(int[] nums) {
        Set<Integer> set =new HashSet<Integer>(); //实例化哈希表,set里每个元素只能存在一种
        int res = -1; 
        for (int num : nums) //num in nums数组里
            if(!set.add(num))  //add成功返回true,不成功返回false。这行返回不成功。
            {  
                res = num;
                break;
            }   
        return res;
    }
}

4.二维数组中的查找

class Solution {
	public boolean findNumberIn2DArray(int[][] array, int target) {
		//判断数组空             一维判断 || 二维判断             第一行长度=0
		if((array==null||array.length==0)||(array.length==1&&array[0].length==0))
			return false;
			
		int i = 0, j = array[0].length - 1;  // ij对应右上角
		while(i <= array.length - 1 && j >= 0)  // i行,j列
		{
			if(array[i][j] == target) return true; // 先判断是否相等,否则ij可能越界
			if(array[i][j] > target) j --; // 排除列
			else i ++; // 排除行
		}
		return false;
	}
}

5.替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。示例如下:
输入:s = “We are happy.”,输出:“We%20are%20happy.”

class Solution {
	public String replaceSpace(String s) {
		int n = s.length(); //对象调用方法,数组不用加括号
		char[] array = new char[n * 3]; //一个空格替换为%20,长度为原来3倍
		int size = 0;
		for(int i = 0; i < n; i ++)
		{
			char c = s.charAt(i);
			if(c == ' ')
			{
				array[size ++] = '%';
				array[size ++] = '2';
				array[size ++] = '0';
			}
			else
				array[size ++] = c;  //array里保存了替换好的字符串
			}
		String news = new String(array, 0 , size); //从0开始,长度为size
		return news;
	}
}

6.从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。示例如下:
输入:head = [1,3,2],输出:[2,3,1]

class Solution {
	public int[] reversePrint(ListNode head) {
		//压栈
		Stack<ListNode> stk = new Stack<ListNode>();
		ListNode temp = head;
		while(temp != null)//一直指向最后一个结点
		{
			stk.push(temp);
			temp = temp.next;
		}
		
		int n = stk.size(); //必须用参数传递,不然会pop掉
		int[] res = new int[n];
		for(int i = 0; i < n; i ++)
			res[i] = stk.pop().val; //val值
		return res;
	}
}

7.重建二叉树


class Solution {
    //树 基本都要用到 递归
	int preindex = 0; //记录下遍历到了哪一个
	int inindex = 0;  //遍历到传入数组长度preorder就结束了,记录是否结束的一个标志
	public TreeNode buildTree(int[] preorder, int[] inorder) {
		return dfs(preorder, inorder, null);
	}
	
	private TreeNode dfs(int[] preorder, int[] inorder, TreeNode finish)
	{   //preorder前序,inorder中序
		if(preindex == preorder.length || (finish != null && inorder[inindex] == finish.val))
			return null;
		//遍历过程 
		//前序 根左右
		TreeNode root = new TreeNode(preorder[preindex ++]);
		//左子树
		root.left = dfs(preorder, inorder, root);
		inindex ++;
		//右子树
		root.right = dfs(preorder, inorder, finish);
		return root;
	}
}

8.二叉树的下一个节点

class Solution {
	public TreeNode inorderSuccessor(TreeNode p) {
		//左根右
		//中序遍历特点
		//一个结点 有右子树 返回一定是 右子树 最左边的结点
		if(p.right != null)
		{
			p = p.right;
			while(p.left != null) p = p.left;
			return p;
		}
		//没有右子树 返回的是 父亲结点
		while(p.father != null)
		{
			if(p == p.father.left)
				return p.father;
			p = p.father;
		}
		return null;
	}
}

9.用两个栈实现队列

class CQueue {
	//栈 先进后出
	//队列 先进先出
	Stack<Integer> stk1, stk2;
	int size;
	public CQueue() {
		stk1 = new Stack<Integer>();
		stk2 = new Stack<Integer>();
		size = 0;
	}

	public void appendTail(int value) {
		//插入一个元素
		//stk1保存 底部存新插入的 顶部存老的
		while(!stk1.isEmpty())
			stk2.push(stk1.pop());
		stk1.push(value);
		while(!stk2.isEmpty())
			stk1.push(stk2.pop());
		size ++;
	}

	public int deleteHead() {
		//删除队列首部元素 
		//删除栈顶
		if(size == 0)
			return -1;
		int res = stk1.pop();
		size --;
		return res;
	}
}

10.斐波那契数列

class Solution {
	public int fib(int n) {
		if(n == 0) return 0;
		if(n?==?1) return 1;
		int first = 0, second = 1;
		int res = 0;
		for(int i = 2; i <= n; i ++)
		{
			res = (first + second) % 1000000007;
			first = second % 1000000007;
			second = res % 1000000007;
		}
		return res % 1000000007;
	}
}

11.旋转数组的最小数字

class Solution {
	public int minArray(int[] nums) {
		int n = nums.length - 1;
		if(n < 0) return -1;
		while(n > 0 && nums[n] == nums[0]) n --;
		if(nums[n] >= nums[0]) return nums[0];
		int l = 0, r = n;
		while(l < r)
		{
			int mid = l + r >> 1; //[l, mid]  [mid + 1, r]
			if(nums[mid] < nums[0]) r = mid;
			else l = mid + 1;
		}
		return nums[l];
	}
}

12.矩阵中的路径

class Solution {
	//回溯法 dfs
	public boolean exist(char[][] board, String word) {
		for(int i = 0; i < board.length; i ++)
			for(int j = 0; j < board[0].length; j ++)
				if(dfs(board, word, 0, i, j))
					return true;
		return false;
	}
	private boolean dfs(char[][] board, String word, int u, int x, int y)
	{
		//先判断边界 后比较相等
		if(x >= board.length || x < 0 || y >= board[0].length || y < 0 || board[x][y] != word.charAt(u))
			return false;
		if(u == word.length() - 1) return true;
		char temp = board[x][y];
		board[x][y] = '*';
		//递归遍历
		boolean res = dfs(board, word, u + 1, x - 1, y) || dfs(board, word, u + 1, x + 1, y) || dfs(board, word, u + 1,x, y - 1) || dfs(board, word, u + 1, x, y + 1);
		board[x][y] = temp;
		return res;
	}
}

13.机器人的运动范围

class Solution {
    int m, n, k;
    boolean[][] visited;
    public int movingCount(int m1, int n1, int k1) {
        //找规律
        //19 20   小8
        //39 40   小8
        //x9 x+1 0 小8
        //普通情况 12  13  +1
        m = m1;
        n = n1;
        k = k1;
        visited = new boolean[m][n];//false
        return dfs(0, 0, 0, 0);
    }
    private int dfs(int x, int y, int sx, int sy)
    {
        //sx sy对应 x y数位之和
        // x 16 y 20 sx 7 sy 2
        //边界优先 m- 1 n -1
        if(x >= m || y >= n || k < sx + sy || visited[x][y]) return 0;
        visited[x][y] = true;
        //sx + sy <= k
        return 1 +  dfs(x + 1, y, (x + 1) % 10 != 0   sx + 1 : sx - 8 , sy) 
                + dfs(x, y + 1, sx, (y + 1) % 10 != 0   sy + 1 : sy - 8);
    }
}

14.剪绳子

class Solution {
    public int cuttingRope(int n) {
        if (n < 2) {
            return 0;
        }
        int[] dp = new int[n + 1];
        dp[2] = 1;
        for (int i = 3; i <= n; i++) {
            for (int j = 1; j < i; j++) {
                dp[i] = Math.max(Math.max(j * dp[i - j], j * (i - j)), dp[i]);
            }
        }
        return dp[n];
    }
}

15.二进制中1的个数

public class Solution {
    // you need to treat n as an unsigned value
    public int hammingWeight(int n) {
        //n & (n - 1)
        //每执行一次 最右边的1变成0
        //unsigned int 
        int count = 0;
        while(n != 0)
        {
            count ++;
            n = n & (n - 1);
        }
        return count;
    }
}

16.数值的整数次方

class Solution {
    public double myPow(double x, int n) {
        //快速幂
        //n用二进制表示
        if(x == 0) return 0;
        long b = n;// 2147483648,2147483647
        double res = 1.0;
        if(b < 0)
        {
            b = -b;//用long防止溢出
            x = 1 / x;
        }
        //快速幂
        while(b > 0)
        {
            if((b & 1) == 1) res *= x;//累乘
            x *= x;以上是关于Notes4剑指offer_03-20题的主要内容,如果未能解决你的问题,请参考以下文章

剑指offer 面试26题

剑指offer 面试32题

剑指offer 面试25题

剑指offer 面试28题

剑指offer 面试18题

剑指offer-25题-复杂链表复制