leetcode刷题 剑指offer 数组与矩阵专题

从今天开始备战春招提前批,每天早中晚各完成三道leetcode题目,主攻剑指offer,按照题目类型解题总结在博客中。每一道题必须用两种解法完成。

数组中重复的数字

题目描述:https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/

解法一:双指针遍历

 public int findRepeatNumber(int[] nums) {
        for(int i = 0; i < nums.length; i++) {
        	for(int j = i + 1 ;j < nums.length ; j++ ) {
        		if(nums[j] == nums[i])
        			return nums[i];
        	}
        }
        return -1;
    }

解法二:利用集合set存储不重复元素的特性进行解题

 public int findRepeatNumber2(int[] nums) {
    	Set<Integer> set = new HashSet<Integer>();
    	int repeat = -1;
    	for(int num : nums) {
    		if(!set.add(num)) {
    			repeat = num;
    			return repeat;
    		}
    	}
    	return repeat;
    }

二维数组中的查找

题目描述:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/

解法1:暴力破解

 public boolean findNumberIn2DArray(int[][] matrix, int target) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
        int rows = matrix.length, columns = matrix[0].length;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                if (matrix[i][j] == target) {
                    return true;
                }
            }
        }
        return false;
    }

解法2:线性查找

public boolean findNumberIn2DArray(int[][] matrix, int target) {
//    	积累对2d数组的异常输入判断
    	if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            return false;
        }
//    	积累对2d数组的行列进行记录
    	int rows = matrix.length;
    	int columns = matrix[0].length;
    	
    	for(int i = 0; i < rows; i++) {
    		if(target > matrix[i][columns - 1]||target < matrix[i][0])
    			continue;
    		for(int j = 0; j < columns; j++) {
    			if(target == matrix[i][j])
    				return true;
    		}
    	}
    	return false;
    }

替换空格

题目描述:https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/

解法1:调用String api

public String replaceSpace(String s) {
    	return s.replace(" ", "%20");
    }

解法2:采用可变字符串SrtingBuilder类

public String replaceSpace(String s) {
    	StringBuilder res = new StringBuilder();
    	for(char c :s.toCharArray()) {
    		if(c == ' ')
    			res.append("%20");
    		else
    			res.append(c);
    	}
    	return res.toString();
    }

顺时针打印矩阵

题目描述:https://leetcode-cn.com/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/

解法一:设置上下左右四边界 不断收缩

public int[] spiralOrder(int[][] matrix) {
		int[] res = {};
		if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
			return res;
		int rows = matrix.length, columns = matrix[0].length;
		int left = 0, right = matrix[0].length - 1, top = 0, bottom = matrix.length -1;
		res = new int[rows*columns];
		int x = 0;//当前值
		while(true) {
			for(int i = left; i <= right; i++) {
				res[x] = matrix[top][i];
				x++;
			}
			top++;
			if(top > bottom) break;
			
			for(int i = top; i <= bottom; i++) {
				res[x] = matrix[i][right];
				x++;
			}
			right--;
			if(right < left) break;
			
			for(int i = right; i >= left; i--) {
				res[x] = matrix[bottom][i];
				x++;
			}
			bottom--;
			if(bottom < top) break;
			
			for(int i = bottom; i >= top; i--) {
				res[x] = matrix[i][left];
				x++;
			}
			left++;
			if(left > right) break;
		}
		return res;
	}

解法2:设置四个方向量

public int[] spiralOrder(int[][] matrix) {
		if (matrix == null || matrix.length == 0 || matrix[0].length == 0)
			return new int[0];
		
		int rows = matrix.length, columns = matrix[0].length;
		boolean[][] visited = new boolean[rows][columns];
		int total = rows*columns;
		int[] order = new int[total];
		int row = 0, column = 0;
//		0,1表示向右,1,0表示向下,0,-1表示向左,-1,0表示向上
		int[][] directions = {{0, 1}, {1, 0},{0, -1},{-1, 0}};
		
		int directionIndex = 0;//方向变换指示,0-3依次表示向右、向下、向左、向上
		for(int i = 0; i < total; i++) {
			order[i] = matrix[row][column];
			visited[row][column] = true;
			int nextRow = row + directions[directionIndex][0];
			int nextColumn = column + directions[directionIndex][1];
			//变换方向的条件
			if(nextRow < 0 || nextRow >= rows || nextColumn < 0 || nextColumn >= columns ||visited[nextRow][nextColumn])
				directionIndex = (directionIndex + 1) % 4;
			
			row += directions[directionIndex][0];
			column += directions[directionIndex][1];
		}
		return order;
	}

第一个只出现一次的字符

题目描述:https://leetcode-cn.com/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/

解法1:采用哈希表,利用hashmap

/**
	 * 找重复这类问题应该想到哈希表这一解决思路
	 * @param s
	 * @return
	 */
    public char firstUniqChar(String s) {
    	char res =' ';
    	if(s.length() == 0) {
    		return res;
    	}
    	HashMap<Character, Boolean> dic = new HashMap<>();
    	char[] sc = s.toCharArray();
    	for(char c : sc) {
    		dic.put(c, !dic.containsKey(c));
    	}
    	for(char c: sc) {
    		if(dic.get(c)) return c;
    	}
    	return ' ';
    	
    }

解法2:利用数组来代替哈希表,记录字符出现次数

public char firstUniqChar2(String s) {
    	int[] count = new int[256];
    	char[] chars = s.toCharArray();
    	for(char c : chars)
    		count[c]++;//字符的asc码
    	for(char c : chars) {
    		if(count[c]==1)
    			return c;
    	} 
    	return ' ';
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值