遍历

PHP 面试官问:你说说Redis的几个过期策略?

混江龙づ霸主 提交于 2019-12-04 04:43:11
在使用redis时,一般会设置一个过期时间,当然也有不设置过期时间的,也就是永久不过期。当设置了过期时间,redis是如何判断是否过期,以及根据什么策略来进行删除的。 设置过期时间  expire key time(以秒为单位) 这是最常用的方式 setex(String key, int seconds, String value) 字符串独有的方式 除了字符串自己独有设置过期时间的方法外,其他方法都需要依靠expire方法来设置时间如果没有设置时间,那缓存就是永不过期如果设置了过期时间,之后又想让缓存永不过期,使用persist key 三种过期策略 定时删除 在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除 优点: 保证内存被尽快释放 缺点: 若过期key很多,删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下,CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key 定时器的创建耗时,若为每一个设置过期时间的key创建一个定时器(将会有大量的定时器产生),性能影响严重 懒汉式式删除 key过期的时候不删除,每次通过key获取值的时候去检查是否过期,若过期,则删除,返回null。 优点: 删除操作只发生在通过key取值的时候发生,而且只删除当前key,所以对CPU时间的占用是比较少的

【排序算法】(7)快速排序

柔情痞子 提交于 2019-12-04 04:18:57
快速排序 2019-11-10 11:43:52 by冲冲 1、概念 快速排序(Quick Sort)使用分治法策略。 ① 基本思想是,选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分;其中一部分的所有数据都比另外一部分的所有数据都要小。然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 ② 快速排序流程 A. 从数列中挑出一个基准值。 B. 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面(相同的数可以到任一边);在这个分区退出之后,该基准就处于数列的中间位置。 C. 递归地把"基准值前面的子数列"和"基准值后面的子数列"进行排序。 2、基本思想 以数列a={30,40,60,10,20,50}为例,演示它的快速排序过程: 在第1趟中,设置x=a[i],即x=30。 ① 从"右 --> 左"查找小于x的数:找到满足条件的数a[j]=20,此时j=4;然后将a[j]赋值a[i],此时i=0;接着从左往右遍历。 ② 从"左 --> 右"查找大于x的数:找到满足条件的数a[i]=40,此时i=1;然后将a[i]赋值a[j],此时j=4;接着从右往左遍历。 ③ 从"右 --> 左"查找小于x的数:找到满足条件的数a[j]=10,此时j=3;然后将a[j]赋值a[i],此时i=1;接着从左往右遍历。 ④ 从

java通过递归统计文件大小

烂漫一生 提交于 2019-12-04 04:17:33
思路就是通过文件的遍历,对一个文件夹中的非目录文件进行大小统计,并对其中目录文件进行相同的遍历操作,代码如下: package word; import java.io.File; import java.io.FileNotFoundException; public class Aa { static iong numb=0;//总大小 public static void main(String[] args) throws FileNotFoundException { // TODO 自动生成的方法存根 String path = "C:\\File"; //要遍历的路径 File file = new File(path); //获取其file对象 fil(file); System.out.println(numb); } public static void fil(File a) throws FileNotFoundException { String path =a.getPath(); File file = new File(path); //获取其file对象 File[] fs = file.listFiles(); //遍历path下的文件和目录,放在File数组中 for(File f:fs){ //遍历File[]数组 if(!f

二叉树的递归遍历

家住魔仙堡 提交于 2019-12-04 04:15:00
hello,大家好,明天就是"double eleven了,不知道大家准备好没有,我们还是加班加点的把二叉树来看一下。 在讲遍历之前,我们首先应该了解一下二叉树是怎么建立的 3 / \ 9 20 / \ 15 7 你可能会看到这样的一颗二叉树,那么这颗二叉树的根节点就是 3 ,而它的两个孩子结点就是 9 和 20 ,在我们建立一颗二叉树的时候,就算它只有一个或者没有孩子,我们也要把另外一个或两个孩子补上去,可以是空格,也可以是其他你自己定义的特殊字符。(但是补了字符的两个孩子就不用管了。) 看了上面,相信你对二叉树已经有了一个印象了,让我们开始吧。 一、结构体 typedef struct node{   elemtype data; //注意这里的 elemtype 前面要设置成 char 类型(也就是字符串), //因为我们的二叉树可能会是字母什么的   struct node*lchild,*rchild; //然后构造它的两个孩子指针,跟之前的 next 差不多,就是一个指向左边的 next 和一个指向右边的 next }node,*btnode; //常规定义 node 数组名和 btnode 指针类型名 二、建立二叉树 3 / \ 9 20 / \ 15 7 关于方法,上面有提到,这里再提两点: 1,在构造数的过程中,因为用到的是递归,所以当我们构造了 3 之后,再构造

第107题:二叉树的层次遍历II

旧城冷巷雨未停 提交于 2019-12-04 03:44:04
一. 问题描述 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如: 给定二叉树 [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其自底向上的层次遍历为: [ [15,7], [9,20], [3] ] 二. 解题思路 本题思路:采用层序遍历和递归的方法进行求解。 步骤一:构建递归函数(全局变量list表存储结果数据,局部表data存储当前一层所有节点) 步骤二:对data表进行遍历,将其子树存储在newdata表中,并进行递归(list,newdata)。 步骤三:当在最底层时,将newdata节点数存储在list表中,并返回上一层接着存储,直到结束。 步骤四:返回list表。 三. 执行结果 执行用时 :1 ms, 在所有 java 提交中击败了100.00%的用户 内存消耗 :36.4 MB, 在所有 java 提交中击败了41.70%的用户 四. Java代码 class Solution { public List<List<Integer>> levelOrderBottom(TreeNode root) { List<List<Integer>> list=new ArrayList<List<Integer>>(); if(root==null) {

第106题:从中序与后序遍历序列构造二叉树

拥有回忆 提交于 2019-12-04 03:39:11
一. 问题描述 根据一棵树的中序遍历与后序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7,20,3] 返回如下的二叉树: 3 / \ 9 20 / \ 15 7 二. 解题思路 本题思路:采用中序和后序遍历的特性进行求解,跟第105题几乎完全相同,只是把前序第一个必定是根节点,改成后序最后一个必定是根节点这点区别,没啥说的,具体可看第105题。 三. 执行结果 执行用时 :21 ms, 在所有 java 提交中击败了37.40%的用户 内存消耗 :51.4 MB, 在所有 java 提交中击败了8.79%的用户 四. Java代码 class Solution { public TreeNode buildTree(int[] inorder, int[] postorder) { if(postorder.length>0) { TreeNode root =new TreeNode(postorder[postorder.length-1]); List<Integer> order=new ArrayList<Integer>(); for(int i=0;i<inorder.length;i++) { order.add(inorder[i]);

P5025 [SNOI2017]炸弹 题解

≯℡__Kan透↙ 提交于 2019-12-04 03:38:05
蒟蒻的第一篇黑题题解(学了这么长时间了才第一道也是没谁了。) 题目链接 ; Solution : 朴素:  根据题目描述,我们可以处理每一个x节点左右爆炸半径范围内的点,然后模拟一次爆炸 (for),遍历每一个点。每当我们遍历到一个点,我们就对这个点在进行一次处理半径+dfs直到没有能遍历的了,直接统计遍历的点数然后输出。 时间复杂度:O(n^2)级别。 于是乎:    是不是可以暴力踩标算了呢? 显然完全接受不了。 因为这个算法要考虑到连边操作。对于每一个点,我们要将它自己连向能够遍历到的边,那么意味着,一个边要被连很多次。 就如下图: 其中编号为1的节点能炸到1 2 3 4 5,2能炸到1 2 3,3能炸到1 2 3 4 5,其中2 3 4挺惨的。 于是有了这么一个线段树建图的思路: 考虑线段树的性质,上层节点可以代表下层节点的一段区间,那么我们是不是也可以建这类的上层边,表示通过这条边能遍历到它对应的下层边的所有点 。 (就是这句精华) 这样我们先把所有点进行从1到n的编号,然后跑线段树的build建边,然后依次对每一个点进行从底层(只能这么理解)到上层节点的连边表示能遍历到上层节点能遍历到的节点。 这样的话,会形成很多环。在对每一个点都进行范围连边以后,对于一个环(或者强连通分量)内的点,自然能互相遍历到,为了方便统计

[LeetCode] 160. Intersection of Two Linked Lists

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-04 03:20:40
求两个链表的交点。给个LC的截图作例子, 两种思路,一个是需要求出两个链表各自的长度,当两者不想等的时候,需要先遍历长的链表,使得其剩下的长度要跟短的链表长度相等,再去找两者的交点。如图所示就是需要先让B移动到node.value = 0的那个节点,再遍历A和B,看看交点在哪里。 时间O(n) 空间O(1) 1 /** 2 * @param {ListNode} headA 3 * @param {ListNode} headB 4 * @return {ListNode} 5 */ 6 var getIntersectionNode = function(headA, headB) { 7 // corner case 8 if (headA === null || headB === null) { 9 return null; 10 } 11 12 // normal case 13 let lenA = len(headA); 14 let lenB = len(headB); 15 if (lenA > lenB) { 16 while (lenA !== lenB) { 17 headA = headA.next; 18 lenA--; 19 } 20 } else { 21 while (lenA !== lenB) { 22 headB = headB.next;

设计模式 迭代器模式

独自空忆成欢 提交于 2019-12-04 03:18:17
迭代器模式:顺序访问一个集合(顺序访问就要求是有序的)。使用者无需知道集合的内部结构(封装) <body>   <div id="div1">     <p>jquery each</p>     <p>jquery each</p>     <p>jquery each</p>   </div>   <script>     var arr = [1, 2, 3];     var nodeList = document.getElementsByTagName('p');     var $p = $('p');     //要对三个变量进行遍历,需要写三个遍历方法     // 第一     arr.forEach(function(item) {       console.log(item);     })     // 第二     var i, length = nodeList.length;     for(i = 0; i < length; i++) {       console.log(nodeList[i]);     }     // 第三     $p.each(function(key, p){       console.log(key, p);     })   </script> </body> 这三种数据结构都是不一样的