`
frank-liu
  • 浏览: 1666771 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论
文章列表
简介     这是一个相对比较简单直接的问题。假设我们有这么一个单链表,需要将它反转过来。对它分析的过程结合图的形式来看会比较清晰直观一点。   分析     我们要通过遍历的方式来反转链表,那么就需要考虑每次反转的时候需要将当前元素指向它原来的前面一个元素。因此,我们需要有一个变量来保存要反转元素的前面一个元素。另外,我们在遍历的时候,要调整当前元素时,为了能够找到后面的结点,需要用到一个额外的变量来指向调整元素,同时调整完之后保证指向前面的元素转而指向当前。     这么个过程显得比较晦涩,用图表的方式来看就很直观了。     假定我们有一个链表,并且声明了两个变量,prev ...
简介     求最大(小)k个元素的问题已经在很多书或者文章上进行了大量的讨论。它有多种解决办法,每一种办法有它所独特适用的一面。同时,这个问题也和求第k大(小)的元素有很紧密的关系。这里,我们以取最小k个元素为例。主要按照《编程之美》这本书上讨论的思路作了一个详细的实现。并对每一种方法作了简单的讨论。 排序方法     这是我们所能想到的比较直接的办法。首先对所有的元素排序,然后取第k个元素。这样这个元素及之前的那些元素就是我们所需要寻找的。具体的实现我们可以考虑用到常用的几种排序方法,比如归并排序和快速排序。另外,还有一种就是采用选择排序作一点修改。 方法一、快速排序的实现 p ...
简介     我们在讨论求一个数组中最小的元素时,相对来说很简单,也很容易找到一个高效率的办法。在一些特殊的情况下甚至还可能有更加优化的方法。如果再把这个问题再深入一点。比如说,我们要求第二小的元素,那么有没有足够高效率的方法呢? 问题描述      在我们思考这个问题的时候,书上的有一个问题就是要求我们来验证在n个元素里,在最坏情况下找到第二小的元素需要经过n + lgn - 2次的比较。那么,我们能不能找到这么一种办法呢?先理一下大致的思路。 解决思路    遍历两次     这种办法相对比较简单直接,就是第一次遍历找到最小的元素。然后在剩下的集合里找最小的那个。这样就找到了 ...
简介     杨氏矩阵是在很多面试和讨论中用到比较多的一个话题。它本身独特的构造使得它的一些增删查改的操作和堆排序以及二分搜索的思想很类似。它本身问题不难,实际操作的时候会稍微有点繁琐。 问题     假定我 ...
简介     counting sort和radix sort和原来的那些通过比较交换来排序的方法不一样。原来的常用排序算法比如插入排序,快速排序等都通过交换元素和递归等手段。而counting sort和radix sort都采用一种类似于映射的方式来实现排序的效果。当然,这种方式之所以会达到O(n)的量级,主要的原因在于这些个排序算法有一个限制,就是首先他们数据的取值范围是在[0, k],数据的个数为n,且n >= k。 counting sort  推导思路     counting sort的过程是基于一个很直观的思考。在前面提到过,我们有n个元素,所有元素的取值范围在 ...
问题的起因     今天在写代码的时候,看到一个比较有意思的写法。假设我们有一个list,它的内容是a = [0, 1, 2, 3, 4, 5, 6, 7, 8 ,9]。如果我们取它反转后的结果,一般我们头脑里默认想到的无非就是reverse这样的方法了。但是它还 ...
前言     在我的前一篇文章里已经对堆排序有了一个详细的介绍。以最大堆为例,我们实现的buildMaxHeap的方法是在将所有元素放置到一个数组中再按照maxHeapify的子流程进行调整。这里有一个前提条件就是所有的数据已经就位 ...
简介         关于堆排序的文章,可以说网上一搜就有一大堆。有的时候自己都在想有没有写这个的必要。仔细看看网上的一些文章,很多不外乎一上来就直接堆代码,让人看的云里雾里。有的则是讲的比较笼统,让人很难懂。于是就想根据自己学习思考的经历,尽量用一种容易理解的方式整理出来。也当是一种学习总结吧。   关于堆         一般我们看到堆这个词,总会想到那些分配对象存储等复杂的数据结构。在堆排序里,很直白的来说,堆就是一个简单的数组。只是我们用一种完全二叉树的角度来看它。以最大堆为例,比如说我们有一棵如下的二叉树:   从上图中,我们发现,如果我们从根结点开始按照从左到右一 ...
问题简介:     以对角线的方式从左至右或者从右至左的遍历一个矩阵。这个矩阵更确切的说是一个行和列都长度相等的方阵。比如说,我们按照从左到右,从上到下的方式遍历一个矩阵。如下图所示: 那么我们遍历的序列将如下:1, 2, 5, 3, 6, 9 4, 7, 10, 13, 8, 11, 14 12, 15, 16. 这是一个比较常见的问题。以前在一些面试中也碰到过。一般来说,只是顺序的遍历每行每列显得过于简单。而通过对角访问的时候,我们可以看到,对应要遍历的行数为矩阵行数的2倍减1.   问题分析: 方法1:     以前面的问题为例,粗看如果要遍历对角的数据,需要首先从第一 ...
简介:     对于一些大的整数,由于计算机本身能够显示的内置数据类型精度有限,在处理一些比较大的整数运算时就不能适用。因此需要考虑用一些结构来辅助运算。一种典型的方式就是通过数组的方式来保存这些大整数。然后通过模拟手工运算的逐位运算。下面对整数的加法和乘法做一个总结。 加法: 位相加的关系:     笼统的来说,加法中数组的每一个元素都对应着整数的每一位。当两个数相加的时候,要把前面的进位和当前的和相加,然后根据结果来进行进位。如果仔细考虑的话,会发现有如下的情况存在: 假设有两个数组a[], b[], 和进位标志carryBit. 如果a[i] + b[i] + carryB ...
简介         求最大公约数和最小公倍数可能是编程中最常见的几个基本问题了。因为他们的基本概念基本上很早的时候就知道了,对他们的求法和他们之间的关系都比较有意思。 基本的数学性质        先从最大公约数这 ...
问题描述         最近在学习一些资料的时候正好看到一些和大整数求余数相关的问题,这些问题粗粗看来似乎有点麻烦。但是当结合一些有关数学的特性来分析时,会觉得很有意思。 问题1: 求一个整数X的N次方除以某个整 ...
equals方法         书上说,我们要比较两个对象是否相等的时候需要定义equals()和hashCode()两个方法。equals方法的完整签名是:equals(Object o). 定义equals方法的过程无非以下几个步骤: 1. 比较传进来的对象是否为空,如果空则返回false。 2. 比较传进来的对象类型是否相同,不同则返回false. 3. 再根据定义的对象比较每个字段是否相等,不等则返回false.   我们都知道,equals()方法意味着一种可传递和交换的对等关系,也就是说,假如A.equals(B)的结果为true的话,那么B.equals(A)的结果也 ...
对数据同步访问封装的策略         我们经常操作一些本身不是线程安全的对象时,在多线程的环境下就会考虑到要采取一些措施来处理。一些典型比如说用synchronized来同步,有的如果情况允许的话使用ThreadLocal变量,还有的会将对象变成immutable的方式。当然,每种方法都需要根据具体问题来分析,不能在保证高并发性和线程安全的情况下完全通用。   同步的数据结构         有一个比较常见的用法就是当我们要访问一些集合类的时候。大多数的集合类比如ArrayList, HashMap之类的都不是线程安全的。为了保证线程安全,我们可能需要用到前面提到的一些同步策略。常 ...
ThreadLocal概念         从字面上来理解ThreadLocal,感觉就是相当于线程本地的。我们都知道,每个线程在jvm的虚拟机里都分配有自己独立的空间,线程之间对于本地的空间是相互隔离的。那么ThreadLocal就应该是该线程空间里本地 ...
Global site tag (gtag.js) - Google Analytics