剑指offer 1-5
Posted lgh544
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer 1-5相关的知识,希望对你有一定的参考价值。
1二维数组的查找:
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
一、暴力法
时间复杂度:
空间复杂度:O(1)
二、从左下找
利用该二维数组的性质:
- 每一行都按照从左到右递增的顺序排序,
- 每一列都按照从上到下递增的顺序排序
改变个说法,即对于左下角的值 m,m 是该行最小的数,是该列最大的数
每次将 m 和目标值 target 比较:
- 当 m < target,由于 m 已经是该行最大的元素,想要更大只有从列考虑,取值右移一位
- 当 m > target,由于 m 已经是该列最小的元素,想要更小只有从行考虑,取值上移一位
- 当 m = target,找到该值,返回 true
用某行最小或某列最大与 target 比较,每次可剔除一整行或一整列
时间复杂度:
空间复杂度:O(1)
//二维数组的查找
public class theSeekOfTwodDmensionalArray {
public static void main(String[] args) {
theSeekOfTwodDmensionalArray seek = new theSeekOfTwodDmensionalArray();
int target = 12;
int[][] array = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
boolean flag = seek.Find(target, array);
System.out.println(flag);
}
public boolean Find(int target, int [][] array) {
boolean flag = false;
int row = array.length-1;
int col = 0;
while(row >= 0 && col <=array[0].length-1) {
if(array[row][col] < target) {
col++;
}else if(array[row][col] > target) {
row--;
}else {
return true;
}
}
return false;
}
}
2替换空格
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
一、调用自带函数
二、用新的數組存
当遇到 " ",就追加 "%20",否则遇到什么追加什么
public class replaceSpaceTest {
public static void main(String[] args) {
replaceSpaceTest replacespace = new replaceSpaceTest();
String str = "dog is animal";
StringBuffer stringbuffer = new StringBuffer(str);
String s = replacespace.replaceSpace(stringbuffer);
System.out.println(s);
}
//调用库函数
public String replaceSpace1(StringBuffer str) {
return str.toString().replace(" ", "%20");
}
//追加
public String replaceSpace(StringBuffer str) {
StringBuilder stringbuilder = new StringBuilder();
for(int i =0; i < str.length();i++) {
if(str.charAt(i) == ‘ ‘) {
stringbuilder.append("%20");
}else {
stringbuilder.append(str.charAt(i));
}
}
return stringbuilder.toString();
}
}
3从尾到头打印链表
输入一个链表,按链表从尾到头的顺序返回一个ArrayList。
使用ArrayList的add(index,value)
import java.util.ArrayList;
public class printListFromTailToHeadTest {
public static void main(String[] args) {
printListFromTailToHeadTest print = new printListFromTailToHeadTest();
link l = new link();
for(int i = 0;i < 10;i++) {
l.add(i);
}
ArrayList<Integer> res = print.printListFromTailToHead(l.root);
System.out.println(res.toString());
}
public ArrayList<Integer> printListFromTailToHead(ListNode listNode){
ArrayList<Integer> list = new ArrayList<>();
while(listNode != null) {
list.add(0,listNode.val);
listNode = listNode.next;
}
return list;
}
}
//链表添加结点
class link{
public ListNode root;
public void add(int val) {
ListNode listNode = new ListNode(val);
if(this.root == null) {
this.root = listNode;
}else {
this.root.add(listNode);
}
}
}
class ListNode{
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
public void add(ListNode listNode) {
if(this.next == null) {
this.next = listNode;
}else {
this.next.add(listNode);
}
}
}
4重建二叉树
根据中序遍历和前序遍历可以确定二叉树,具体过程为:
- 根据前序序列第一个结点确定根结点
- 根据根结点在中序序列中的位置分割出左右两个子序列
- 对左子树和右子树分别递归使用同样的方法继续分解
例如:
前序序列{1,2,4,7,3,5,6,8} = pre
中序序列{4,7,2,1,5,3,8,6} = in
- 根据当前前序序列的第一个结点确定根结点,为 1
- 找到 1 在中序遍历序列中的位置,为 in[3]
- 切割左右子树,则 in[3] 前面的为左子树, in[3] 后面的为右子树
- 则切割后的左子树前序序列为:{2,4,7},切割后的左子树中序序列为:{4,7,2};切割后的右子树前序序列为:{3,5,6,8},切割后的右子树中序序列为:{5,3,8,6}
- 对子树分别使用同样的方法分解
- 时间复杂度:O(n)O(n)O(n)
空间复杂度:O(n)O(n)O(n)
import java.util.Arrays;
public class reconstructionOfBinaryTree {
public static void main(String[] args) {
reconstructionOfBinaryTree binaryTree = new reconstructionOfBinaryTree();
int[] pre = {1,2,4,7,3,5,6,8};
int[] in = {4,7,2,1,5,3,8,6};
TreeNode root = binaryTree.reConstructBinaryTree(pre,in);
root.preOrder();
}
//递归
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length == 0 || in.length == 0) {
return null;
}
TreeNode node = new TreeNode(pre[0]);
for(int i = 0; i < in.length; i++) {
if(in[i] == pre[0]) {
node.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i));
node.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1, in.length));
break;
}
}
return node;
}
}
class TreeNode{
int val;
TreeNode left;
TreeNode right;
public TreeNode(int val) {
this.val = val;
}
//验证构建的二叉树 前序遍历
public void preOrder() {
System.out.println(this.val);
if(this.left != null) {
this.left.preOrder();
}
if(this.right != null) {
this.right.preOrder();
}
}
}
5用两个栈模拟队列
用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型
- 当插入时,直接插入 stack1
- 当弹出时,当 stack2 不为空,弹出 stack2 栈顶元素,如果 stack2 为空,将 stack1 中的全部数逐个出栈入栈 stack2,再弹出 stack2 栈顶元素
- push时间复杂度:
pop空间复杂度:O(1)
import java.util.Stack;
public class twoStacksAnalogqueue {
public static void main(String[] args) {
twoStacksAnalogqueue stack = new twoStacksAnalogqueue();
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.pop());
stack.push(4);
System.out.println(stack.pop());
stack.push(8);
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
}
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
if(stack2.isEmpty()) {
while(!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
}
以上是关于剑指offer 1-5的主要内容,如果未能解决你的问题,请参考以下文章