剑指Offer
zxl*
这个作者很懒,什么都没留下…
展开
-
删除链表中的重复的节点
题目描述在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5思路因为不确定头节点是否重复,所以要先定义一个预节点Head,如果当前节点与下一个节点的val相同,并且下一个节点不为空,则通过循环将重复节点找到,否则的话,当前节点与下一个节点不同或者当前这个节点是最后的一个节点,则将当前这个节点加入Head链表,遍历完成整个链接,返回原创 2020-07-21 17:04:17 · 319 阅读 · 0 评论 -
二进制中1的个数
题目描述输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。思路定义一个flag,将其的二进制表示中1的位置从最低位开始向左移动,一直移动到最高位,每次都将flag与整数进行位移运算,这样能判断32位中都有哪一位是1,当flag左移到最高位后,flag会变成0,结束循环代码public int NumberOf1(int n) { int count = 0; if(n == 0){ return 0; } int flag = 1;原创 2020-07-21 11:06:12 · 100 阅读 · 0 评论 -
剪绳子
题目描述给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1,m<=n),每段绳子的长度记为k[1],...,k[m]。请问k[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。思路对于小于3的数一一进行列举,分别返回,对于大于3的数进行分析,我们要尽可能多剪长度为3的绳子,才能保证最终的乘积可能是最大值,分为一下三种情况:正好能够剪3的整数倍times,最大原创 2020-07-15 10:32:14 · 308 阅读 · 0 评论 -
机器人的运动范围
题目描述地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?思路这是一个回溯问题,从(0,0)开始判断当前格子行坐标和列坐标之和是否大于K,如果大于则将当前的count返回,若不大于则将flag矩阵中的对应位原创 2020-07-15 09:40:53 · 139 阅读 · 0 评论 -
二叉树的下一个节点
题目描述给定一个二叉树和其中的一个结点A,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。思路中序遍历:先遍历左孩子,然后根节点,然后右孩子1)节点A有右子树,那么它的下一个节点就是它右子树的最左边的节点。2)节点A没有右子树,那么我们就要向上遍历,知道找到一个节点B,这个节点B是它父节点的左孩子,则这个B节点的父节点就是节点A的下一个节点;如果一直向上遍历,直到遍历到了根节点,则表示这个节点A没有下一个节点代码public原创 2020-07-03 10:15:06 · 114 阅读 · 0 评论 -
重建二叉树
题目描述输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。思路根据二叉树的前序遍历可以知道根节点是1,在中序遍历中根节点前的为左子树{4,7,2},根节点后的为右子树{5,3,8,6},通过递归的方法,在分别取构建左右子树,最后将构建好的左右子树放进根节点中。代码 // Definition for原创 2020-07-03 09:05:16 · 80 阅读 · 0 评论 -
数字在排序数组中出现的次数
题目描述统计一个数字k在排序数组中出现的次数。第一种首先想到的就行遍历数组,统计数字。但是如果数字k在数组中不存在或者最后是数组中的最后一位,则需要遍历整个数组,时间复杂度为O(n)。代码public int GetNumberOfK(int [] array , int k) { if(array.length == 0){ return 0; } int count = 0; for(int i=0;原创 2020-07-01 11:37:39 · 152 阅读 · 0 评论 -
数组中出现次数超过一半的数字
题目描述数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。思路创建HashMap存储对应的数字以及次数,遍历整个数组,判断该数字是否HashMap中是否存在,若不存在则将数字放进map中,若存在则将次数加1,然后判断次数是否超过数组长度的一半,若超过则返回该数字,若遍历完整个数组都找不到数字次数超过数组长度一半的数字,则返回0。代码原创 2020-07-01 09:12:37 · 101 阅读 · 0 评论 -
数组中只出现一次的数字
题目描述一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。思路:因为数字只存在一次或者两次,所以可以定义一个ArrayList用于添加数组中的元素,若元素已经在ArrayList存在,则在ArrayList删除该元素,表示这个元素是出现两次的元素,遍历完成数组,最后在ArrayList中剩下的元素则为出现一次的数字。若有有的元素出现奇数次,可以使用HashMap来进行存储,最后遍历这个HashMap就可以了。代码:import java.u原创 2020-06-29 17:38:07 · 121 阅读 · 0 评论 -
调整数组顺序使奇数位于偶数前面
题目描述输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。思路:我们定义一个新的数组,存储旧数组中的偶数,同时删除旧数组中的偶数,当遍历完成旧数组时,所有的偶数都存储进新数组中,将新数组中的元素都拼接再旧数组的末尾。代码:public class Solution { public void reOrderArray(int [] array) {原创 2020-06-29 17:29:57 · 120 阅读 · 0 评论 -
从尾到头打印链表
题目描述输入一个链表,按链表从尾到头的顺序返回一个ArrayList。思路:对于单向链表我们我们只能从头向尾部读取,无法从尾部向头读取链表,将读取的数据压栈,遍历完数组时压栈完成,再读取栈,就完成了从尾至头的顺序返回链表。代码:import java.util.ArrayList;import java.util.Stack;import org.junit.Test;public class LinkNode3 { public class ListNode {原创 2020-06-29 17:11:22 · 135 阅读 · 0 评论 -
替换空格
题目描述请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。思路原创 2020-06-28 22:59:44 · 96 阅读 · 0 评论 -
数组中重复的数字
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。思路:数组中的数字都在0 - n-1的范围内,如果这个数组中没有重复的数字吗,那么数组中元素进行排序之后,数字i将出现在下标为i的位置,由于数组中重复的元素,有的位置可能存在多个数字,有的位置可能没有数字。我们从头到尾扫描这个数组,扫描到下原创 2020-06-28 15:10:18 · 94 阅读 · 0 评论 -
二维数组中的查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。思路:数组是从上至下,从左至右都是逐渐变大的,我们先选取一个数字,分3中情况来分析查找的过程,当数组中选取的数字正好和整数相同,直接返回true。当选取的数字小于整数,要查找的数字应该在当前数字的下方或者右边。当选取的数组大于整数,要查找的数字应该在当前数字的上方或者左边。从二维数组的最右侧的第一行的元素开始原创 2020-06-28 15:10:32 · 110 阅读 · 0 评论