描述:输入一个链表的头节点,从尾到头打印每个节点的值. 思路:从尾到头打印,即为“先进后出”,则可以使用栈来处理:考虑递归的本质也是一个栈结构,可递归输出. 考点:对链表.栈.递归的理解. package com.java.offer; import java.util.Stack; /** * @since 2019年2月14日 下午2:13:20 * @author xuchao * */ public class P6_PrintListInReversedOrder { public s…
剑指Offer - 九度1511 - 从尾到头打印链表2013-11-29 21:08 题目描述: 输入一个链表,从尾到头打印链表每个节点的值. 输入: 每个输入文件仅包含一组测试样例.每一组测试案例包含多行,每行一个大于0的整数,代表一个链表的节点.第一行是链表第一个节点的值,依次类推.当输入到-1时代表链表输入完毕.-1本身不属于链表. 输出: 对应每个测试案例,以从尾到头的顺序输出链表每个节点的值,每个值占一行. 样例输入: 1 2 3 4 5 -1 样例输出: 5 4 3 2 1 题意分…
题目:输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回). 首先定义一下链表中的节点,关于链表这个数据结构在另外一篇文章中会详细讲 function ListNode(val) { this.val = val; this.next = null; } 理清一下思路,我们要反转一个链表,可以遍历链表,将链表中的元素存到一个数组中,然后按照反转的顺序保存 好了,思路清晰了,那我们当然是要用栈这个数据结构,要记住,在改变顺序或者操作数组的时候,是和栈分不开的 var reservep…
题目:从尾到头打印链表 考点:链表 题目描述:输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 法一:ArrayList头插法 /** * public class ListNode { * int val; * ListNode next = null; * * ListNode(int val) { * this.val = val; * } * } * */ import java.util.ArrayList; public class Solution { //Arra…
题目描述 输入一个链表,从尾到头打印链表每个节点的值. 题目分析 比较简单,主要注意下从尾到头,可以用栈可以用递归,我给出我比较喜欢的代码吧 代码 /* function ListNode(x){ this.val = x; this.next = null; }*/ function printListFromTailToHead(head) { // write code here const res = []; let pNode = head; while (pNode !== null…
  题目描述:   输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   解题思路:   (三种方法:借助栈.递归.列表的首位插入)   从头到尾打印链表比较简单,从尾到头很自然的可以想到先将链表进行反转,然后再打印.但是,通常我们不希望改变原链表的结构,这是一个只读操作.   因此,我们进一步分析,可以发现排在后面的先输出,这是一个典型的"后入先出"的思想,因此很自然的可以想到用栈来实现,每遍历一个结点,可以将其压入栈中,遍历结束后再逐个弹栈,将结点值存入ArrayL…
题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList.   题目解析 方法1:建立两个vector,第一个用来存储正向访问的数据,第二个用来反向存储. /** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : * val(x), next(NULL) { * } * }; */ class Solution { public: vector<int> printListFr…
题目: 输入一个链表的头结点,从尾到头反过来打印出每个结点的值.结点定义如下: public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; } } 思路: 从尾到头,我们首先想到的就是栈这个结构,栈是先进先出的结构,先进来的元素最后再出去,所以本题我们可以考虑用栈来解决 想到栈的同时我们也应该联想到递归 代码: import java.util.Stack; import o…
题目描述 输入一个链表,从尾到头打印链表每个节点的值.…
题目:输入一个链表的头结点,从尾到头反过来打印出每一个节点的值 考察 单链表操作.栈.递归等概念. 理解:要实现单链表的输出,那么就须要遍历.遍历的顺序是从头到尾.而节点输出的顺序是从尾到头.因此,先遍历到的节点后输出.这是一个典型的 "后进先出". 要实现这种输出,能够使用栈,或,递归. 通过这道题,让我对 "递归在本质上就是一个栈结构" 理解的更加深刻. 代码例如以下: /*********************************************…
题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值.链表节点定义如下: struct ListNode{ int m_nKey; ListNode* m_pNext; } 测试用例: 功能测试(输入的链表有多个节点:输入的链表只有一个节点). 特殊输入测试(输入的链表头结点指针为nullptr). 测试代码: void Test(ListNode* pHead) { PrintList(pHead); PrintListReversingly_Iteratively(pHead); p…
一.题目大意 输入一颗二叉树,判断该二叉树是否为平衡二叉树(AVL树). 二.题解 <剑指offer>上给出了两种解决方式: 1.第一种是从根节点开始,从上往下遍历每个子节点并计算以子节点为根节点的子树的高度,通过判断左右子树的高度差是否大于1来判断是否为AVL树.其中计算子树的高度,利用了TreeDepth函数(具体可见<剑指offer(第二版)>P272).其中TreeDepth的思想如下: (1)计算一颗二叉树的高度,可以将该问题转化成求子树的高度+1.如果根节点只有左子树的…
剑指Offer 按题号排序 面试题 3:数组中重复的数字 面试题 4:二维数组中的查找 面试题 5:替换空格 面试题 6:从头到尾打印链表 面试题 7:重建二叉树 面试题 8:二叉树的下一个节点 面试题 9:用两个栈实现队列 面试题 10:斐波那契数列 面试题 11:旋转数组中最小数字 面试题 12:矩阵中的路径 面试题 13:机器人的运动范围 面试题 14:剪绳子 面试题 15:二进制中1的个数 面试题 16:数值的整数次方 面试题 17:打印从1到最大的n位数 面试题 18:删除链表中的节点…
3.数组中重复数字:每个位置放置数字与下标对应相等 O(n) 4.二维数组中的查找:右下角开始比较 O(m+n) 5.替换空格:python直接替换 6.从尾到头打印链表: 借助栈或直接利用系统调用栈 // 创建链表(设置next节点时就会创建下一个节点), 打印链表(最后打印nil) 7.重建二叉树:前序中序遍历特点递归重建左右子树 xxx8.二叉树的下一个节点:根据中序遍历特点,按有无右子树分情况讨论 xxx9.两个栈实现队列:栈的特点 10.斐波那契数列:递归思想,循环方法自下而上计算O(…
题目描述 思路分析 Java代码 代码链接 题目描述 从尾到头打印链表,将其添加到ArrayList当中输出 思路分析 递归的思路 利用栈 Java代码 public class Offer006 { public static void main(String[] args) { ListNode ListNode1 = new ListNode(1); ListNode ListNode2 = new ListNode(2); ListNode ListNode3 = new ListNod…
一.题目大意 给你一个数n,要求返回第n个丑数.其中,丑数的定义如下: 丑数是指只包含因子2.3和5的数.(数字1也是丑数,不过是个特例)引用<剑指offer>上的话来说,对于一个数M,如果M能被2整除,就连续除以2:若果能被3整除,就连续除以3:如果能被5整除,就连续除以5.如果最终的结果是1的话,那么M就是丑数,否则M不是丑数.以下是判断一个数是否为丑数的代码: bool IsUglyNumber(int num) { while(num % 2 == 0) num /= 2; while…
具体的题目大意和参考思路在此处不详述(见<剑指offer>),实质就是在中序遍历的过程中调整指针的指向,关于中序遍历有递归和非递归两种操作,所以此处也用了两种方法. 方法1(递归法): 代码如下: class Solution { public: TreeNode* Convert(TreeNode* pRootOfTree) { if(pRootOfTree == nullptr) return nullptr; TreeNode * pre = nullptr;//中序遍历中当前节点的前一…
一.题目描述 把n个骰子仍在地上,所有的骰子朝上的一面的点数之和为s,输入n,打印出s所有可能的值出现的概率. 二.题解 <剑指offer>上给出的两种方法,尤其是代码,晦涩难懂且没有注释.而n个骰子的问题实质就是一个动态规划问题,所以文本主要从动态规划的角度来求解这个问题.首先该问题具备DP的两个特征:最优子结构性质和子问题的重叠性.具体的表现在:(1)n个骰子的点数依赖于n-1个骰子的点数,相当于在n-1个骰子点数的基础上再进行投掷.(2)求父问题的同时,需要多次利用子问题.由此定义状态转…
一.题目描述 求1+2+3+...+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字以及条件判断语句 (即三元运算符,A? B : C) 二.题解 虽然求和问题本身很容易,但加上这么多限制条件的话,整个问题似乎就不那么简单了.<剑指offer>虽然给出了四种解决方法,但这四种方法都是基于C++的语言特性求解的,并不是通用的解法.所以,本文旨在给出通用的解法.首先,根据以上的限制条件,可以考虑的角度只有两种(个人看法)一个是递归,另一个是位运算.从位运算…
一.题目大意 给定一个数组A,对于数组A中的两个数字,如果排在前面的一个数字大于(必须大于,等于不算)后面的数字,则这两个数字组成一个逆序对.要求输出数组A中的逆序对的总数.例如,对于数组{7,5,6,4},一共存在5个逆序对,分别是(7,5).(7,6).(7,4).(5,4).(6,4). 注:根据题意可知,必须根据原数组中元素的相对顺序来统计,给定的数组时怎样,那就按照怎样的顺序. 二.思路分析 方法1:暴力破解.双重循环来判断出所有的逆序对数,时间复杂度为O(N^2),空间复杂度为O(1…
面试题5:替换空格 题目要求: 实现一个函数,把字符串中的每个空格都替换成“%20”,已知原位置后面有足够的空余位置,要求改替换过程发生在原来的位置上. 思路: 首先遍历字符串求出串中空格的数量,求出替换之后字符串的总长度(每替换一个空格,长度加2).做法是从字符串的后面向前复制和替换.有2个指针p1.p2,p1指向原字符串的尾,p2指向替换之后的字符串的尾.接下来向前移动指针p1,逐个的将p1指向的字符复制到p2指向的位置,碰到空格时,p1向前移动一格,在p2之前插入字符串"%20"…
面试题10:斐波那契数列 题目要求: 求斐波那契数列的第n项的值.f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2) n>1 思路:使用循环从下往上计算数列. 考点:考察对递归和循环的选择.使用递归的代码通常比循环简洁,但使用递归时要注意一下几点:1.函数调用的时间和空间消耗:2.递归中的重复计算:3.最严重的栈溢出.根据斐波那契数列递归形式定义很容易直接将代码写成递归,而这种方式有大量重复计算,效率很低. 解法比较: 解法3,4将问题数学化,借助数学工具的推导,从根本上减低时…
描述:使用两个栈实现一个队列.队列中实现尾部插入和头部删除函数. 思路:stack1负责插入,stack2负责弹出,如果stack2为空了,将stack1的元素依次弹出并存放到stack2中,之后对stack2进行弹出操作. 考点:对栈和队列的理解:对泛型的使用等. /** * Copyright(C) 2019 Hangzhou Differsoft Co., Ltd. All rights reserved. * */ package com.java.offer; import java.…
描述:给定一棵二叉树和其中的一个节点,找出中序遍历序列的下一个节点.树中应定义指向左节点.右节点.父节点的三个变量. 思路: 1.如果输入的当前节点有右孩子,则它的下一个节点即为该右孩子为根节点的子树的最左边的节点,比如2->5,1->3 2.如果输入的当前节点没有右孩子,就需要判断其与自身父节点的关系: 2.1如果当前节点没有父节点,那所求的下一个节点不存在,返回null. 2.2如果输入节点是他父节点的左孩子,那他的父节点就是所求的下一个节点,比如4->2 2.3如果输入节点是他父节…
描述:输入某二叉树的前序遍历和中序遍历结果,重建该二叉树.假设前序遍历或中序遍历的结果中无重复的数字. 思路:前序遍历的第一个元素为根节点的值,据此将中序遍历数组拆分为左子树+root+右子树,前序遍历数组拆分为root+左子树+右子树.再对左右子树进行同样的操作. 考点:对二叉树不同遍历方法的掌握. /** * Copyright(C) 2019 Hangzhou Differsoft Co., Ltd. All rights reserved. * */ package com.java.o…
思想:前序(根左右),中序(左根右),后序(左右根) 前序非递归遍历: 首先判断根是否为空,将根节点入栈 1.若栈为空,则退出循环 2.将栈顶元素弹出,访问弹出的节点 3.若弹出的节点的右孩子不为空则将右孩子入栈 4.若弹出的节点的左孩子不为空则将左孩子入栈 5.返回1 后序遍历非递归: 前序:根->左->右 后序:左->右->根 可以把后序当作:根->右->左,然后再反转一下即可 中序遍历非递归: 根据中序遍历的顺序,对于任一结点,优先访问其左孩子,而左孩子结点又可以…
面试题3:数组中重复的数 题目要求: 在一个长度为n的数组中,所有数字的取值范围都在[0,n-1],但不知道有几个数字重复或重复几次,找出其中任意一个重复的数字. 解法比较: /** * Copyright(C) 2019 Hangzhou Differsoft Co., Ltd. All rights reserved. * */ package com.java.offer; /** * 一个长度为n的数组,值的范围在0~n-1内,有一个或多个数字重复,求其中任意一个 * * @since…
面试题2:实现单例模式 题目要求: 设计一个类,只能生成该类的一个实例. /** * 单例模式 * 定义:指实现了特殊模式的类,该类仅能被实例化一次,产生唯一的一个对象 * 应用举例:windows的任务管理器,回收站,web应用的配置对象,spring中的bean默认也是单例 * 分类:饿汉式,懒汉式,双检锁,静态内部类,枚举 * 评价指标有:单例(必须),线程安全,延迟加载,防止反序列化产生新对象,防止反射攻击 * 实现方法的选择:一般情况下直接使用饿汉式就好了,要求延迟加载时倾向于用静态内…
1.排序算法比较: 2.java实现 快排: /** * 快排 * * @since 2019年2月26日 下午1:37:34 * @author xuchao */ public class QuickSoft { public static void quickSoft(int[] data,int start,int end) { if(start>=end) { return; } int m = quickSoftPartition(data, start, end); quickSo…
面试题4:二维数组中的查找 题目要求: 一个二维数组中,每一行从左到右递增,每一列从上到下递增.输入一个整数,判断数组中是否含有该整数 /** * @since 2019年2月13日 下午5:08:50 * @author xuchao * 二维数组,从左到右递增,从上到下递增,输入一个整数,判断数组中是否含有 * * 思路: * 从最后一行第一列与目标值比较,若大于目标值,则行下标-1;若小于目标值,则列下标+1 * */ public class P4_FindInPartiallySort…