剑指offer
一、剑指offer 03.数组中的重复数字
- 剑指 Offer 03. 数组中重复的数字
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
- 解题思路
1、采用HashSet,因为它不允许元素重复
2、HashSet中的add方法,当添加元素集合中没有该元素时才添加并返回true
3、当add方法返回值为false时说明该元素重复了,即找到了重复数字
class Solution {
public int findRepeatNumber(int[] nums) {
int res=-1; //用来记录重复的数字,因为所有数都是0~n-1,所以初始化为-1
Set <Integer> set=new HashSet<Integer>();//因为HashSet中不允许元素重复
for(int num:nums){ //遍历数组
if(!set.add(num)){ //HashSet中的add方法 添加成功返回true 添加失败返回false
res=num; //添加失败说明该数字重复 将数字赋值给res
break; //找到重复数字结束遍历
}
}
return res; //返回重复数字
}
}
二、剑指offer 04.二维数组中的查找
- 剑指 Offer 04. 二维数组中的查找
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
- 解题思路
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
//先判空 若为空格则返回false
if((matrix==null||matrix.length==0)||(matrix.length==1 && matrix[0].length==0))
return false;
int i=0;
int j=matrix[0].length-1;//对应右上角
while(i<=matrix.length-1 && j>=0){ //判断便捷
if(target==matrix[i][j]) return true; //若a[i][j]==target 则返回true
if(target<matrix[i][j]) j--; //若target<a[i][j]右上角 则第j列不用看 j--
else if(target>matrix[i][j]) i++; 若target>a[i][j]右上角 则第i行不用看 i++
}
return false; //若二维数组找完没有返回true ,即为没有该数字 返回false
}
}
三、剑指offer 05.替换空格
- 剑指 Offer 05. 替换空格
请实现一个函数,把字符串 s 中的每个空格替换成"%20"。
-解题思路
1.创建一个字符数组将结果先放入字符数组(因为要遍历字符串 charAt()方法返回的是字符串),最后再将字符数组转为字符串
2.创建一个大小为n3的字符数组,因为一个空格换三个字符 所以长度为n 的字符串最多需要的数组长度为n3
3.创建一个可存放字符的数组小标size ,从0开始
4.遍历数组,若为空格则将‘%20’放入size下标对应得字符数组中,若不是则将该字符放入字符数组(记得size++)
5.将字符数组转为字符串,并返回
class Solution {
public String replaceSpace(String s) {
int n=s.length();
//结果先放在char 数组中 因为一个空格换三个字符 所以长度为n 的字符串最多需要的数组长度为n*3
char [] array=new char[n*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{ //若不为则不需替换直接将c放入数组
array[size++]=c;
}
}
String news=new String (array,0,size); //最后将字符数组转换为字符串
return news; //返回字符串
}
}
利用String内置函数也可以解
class Solution {
public String replaceSpace(String s) {
return s.replace(" ","%20");
}
}
四、剑指offer 06.从尾到头打印链表
- 剑指 Offer 06. 从尾到头打印链表
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
- 解题思路
1.因为栈先入后出,所以使用栈
2.遍历链表,将他们压栈
3.创建数组,将出栈的值放入数组
4.返回数组
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
//压栈
Stack<ListNode> stk=new Stack<>();//创建一个栈
ListNode temp=head;
while(temp!=null){
stk.push(temp); //循环链表进行压栈
temp=temp.next;
}
int res[]=new int [stk.size()]; //因为返回值为数组
int size=stk.size(); //获取res大小方便遍历 因为pop每次size都会变小
for(int i=0;i<size;i++){
res[i]=stk.pop().val; //出栈将数值给res[i]
}
return res;
}
}
五、剑指offer 07.重建二叉树
- 剑指 Offer 07. 重建二叉树 剑指 Offer 07. 重建二叉树
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
- 解题思路
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
HashMap<Integer,Integer> inmap=new HashMap<>();//标记中序遍历
int [] pre;//保留的先序遍历
public TreeNode buildTree(int[] preorder, int[] inorder) {
pre= preorder;
for(int i=0;i<inorder.length;i++){
inmap.put(inorder[i],i);//根据这个值找到中序遍历的下标索引
}
return helper(0,0,inorder.length-1);
}
//先序遍历索引,中序遍历左边界 ,中序遍历右边界
public TreeNode helper(int pre_root,int in_left,int in_right){
if(in_left>in_right) return null;
TreeNode node =new TreeNode(pre[pre_root]);
int i=inmap.get(pre[pre_root]);//根据值获取中序遍历的位置
//先序遍历索引,中序遍历左边界 ,中序遍历右边界 如表
node.left=helper(pre_root+1,in_left,i-1);
node.right=helper(pre_root+i-in_left+1,i+1,in_right);
return node;
}
}