LeetCode刷题记录2

创建于

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。  

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  • 基本思路是二分查找,三个指针分别是首尾和中间
  • 数组为空
  • 数组只有一个值
  • 形如[3,3,1,3]的数组,只能顺序查找(首尾和中间都是相等的)
class Solution {
    public int minArray(int[] numbers) {
        if(numbers==null){
            return -1;
        }

        if(numbers.length==1){
            return numbers[0];
        }
        
        int head=0,min;
        int tail=numbers.length-1;
        if(numbers[head]==numbers[tail]&&numbers[(head+tail)/2]==numbers[head]){
            for(int i=1;i<tail;i++){
                if(numbers[i-1]>numbers[i]){
                    return numbers[i];
                }
            }
        }

        while(head!=tail-1){
            min=(head+tail)/2;
            if(numbers[min]<=numbers[tail]){
                tail=min;
                continue;
            }
            if(numbers[head]<=numbers[min]){
                head=min;
                //continue;这个地方在末尾,有没有continue都一样
            }
        }
        return tail==1?(Math.min(numbers[0], numbers[1])):numbers[tail];
    }
}
```java

SQL注入

创建于

一些教程的记录:

SQLi-LABS是 印度程序员(GitHub用户名Audi-1)写的一个用于学习SQL注入的教程。此教程包含的脚本可以在用户本地的MYSQL中创建一系列数据库,使用localhost访问以作为靶机进行练习。

实际上,网上已经有一个已经搭建好的靶机,运行于腾讯云的Ubuntu操作系统上,地址为http://111.231.88.117/sqli_lab/sqli-labs-php7/.不过这个不是我搭建的,如果不能用了不要找我. =_=

配置环境:mysql+Apache

不建议在Windows上配置环境,除非本来电脑上没有MySQL,这时可以用PHPstudy这个集成环境.

Apache的注意事项

https://blog.csdn.net/maq56310/article/details/80580286

如果443端口被占用,可以用

netstat -ano //查看端口号对应的pid
taskkill /f /pid 1234 //杀死1234进程,也可在任务管理器中杀死.

conf/httpd.conf的监听端口默认为80,改为8088解决

Sqli-labs文件夹应该放在C:\Apache24\htdocs下,而不是网上所有的其他博客说的web或者www

启动只能用 http://localhost:8088/Sqli-labs/ ,不能用IP地址,不然打不开

实际上,Windows环境下搜到的各种解决方法都是不可用的,并且存在破坏本机环境的情况,我的mysql就不能用了.改用macos

在macOS上配置环境

很简单,首先安装docker,然后

sudo docker pull acgpiano/sqli-labs

如果网络错误,建议开全局代理,之后

docker run -dt --name sqli-lab -p 80:80 acgpiano/sqli-labs:latest

第一个80是主机的端口,将docker内的环境映射到物理机的80端口中

浏览器打开localhost即可访问

重启以后,需要

docker stop sqli-lab
docker rm sqli-lab
docker run -dt --name sqli-lab -p 80:80 acgpiano/sqli-labs:latest

并且在网页里需要重新建数据库

基于错误的

Less1 单引号注入,字符串,get

get是直接把参数写在URL里面的(-_-)!

MySQL中的注释是– (两个减号一个空格,在URL中,最后的空格会被去掉,因此使用的时候用的是–+)

输入 ?id=1 返回

Your Login name:Dumb
Your Password:Dumb

数字改成2,返回另外两个name和password

输入 ?id=2’ 返回

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''2'' LIMIT 0,1' at line 1

猜测SQL语句是 select xxx from xxx where ‘’ limit 0,1

获取列数

试图获取其他的信息需要使用union语句.union语句需要前面的结果和后面的结果的列数相同,因此需要得到原有的SQL语句查询结果中共有几列.接下来试图获取表的列数,方法是使用order by.在URL中输入:

?id=1 order by 3 --+

可以正常返回结果,说明该表至少有三列.确定列数,只要order by 后面的数字一个一个试就可以了.由于最开始时已经返回了两个值,所以从3开始试即可.这个表中,试到4,即

?id=1 order by 4 --+

就出现了错误提示,所以共有三列.

而实际上页面回显的语句只有两个,因此需要知道显示的是哪两列,输入

?id=-1’ union select 1,2,3 --+

结果会显示数字2,3所以可知显示的是第2,3列.由于结果只显示第一行查询结果,这行语句中,id=-1使得union左边的语句查询结果为空以显示右边自行构造的SQL语句的结果,-1也可替换为其他的猜测不存在的数字.

获取其他信息

数据库名:

-1' union select 1,2,group_concat(schema_name) from information_schema.schemata --+

group_concat让结果变成一行,因为返回的结果只显示一行=_=

表名:

?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema= 'security' --+

列名:

?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name= 'users' --+ 得到列名为id,username,password

数据表:
?id=-1’ union select 1,group_concat(username),group_concat(password) from users –+

less2,3,4 基于错误的

经过艰难的测试,靶机1,2,3,4的SQL语句实际上大同小异,区别主要在id被什么符号包裹在内,写出正确的闭合的SQL语句即可.他们可能被包裹在括号,双引号,单引号,或者前面几个的组合(或者啥也没有)的里面,只要有几个错误多试几次就容易看出来.

less11 Post类型

单引号
这个就是我们看见的输入账号和密码的类型了

用户名输入:database()–+, 密码输入1=1 –,报错:…use near ‘database()–+’ and password=’1=1 –’ LIMIT 0,1’ at line 1.从这里看出,用户名和密码的验证是在同一行的,并且先验证用户名,那么我们在用户名的位置添加注释,尝试填写用户名为aaa’or 1=1 – (此处有空格),密码填入123(密码可以不填),显示登陆成功,输出提示:Your Login name:Dumb Your Password:Dumb.

这个其实很简单,发现用户名和密码在同一行,那么在用户名那个地方填写注入语句即可.

布尔,时间,盲注

这种类型的SQL注入是最繁琐的.无论URL中的参数输入什么,都返回同一句话.

这样以上基于错误的方式就不能奏效了.因此采用另一种方法,利用if()和sleep(),观察网页加载的时间,从而判断语句是否正确执行.尝试: ?id=1’ and sleep(3) –+,发现网页加载明显有延迟,说明注入成功.获取数据库名等的方法也与有回显的注入方法完全不一样.简而言之,没有回显的注入需要猜测或者穷举(可以用二分法查找,更快)结果中的每一个字符,来获得想要的结果.

获取数据库名称长度: ?id=1’ and if(length(database())=8 , sleep(3), 1) –+,这行语句有明显加载延迟,说明数据库名称长度是8.在实际编写的脚本中往往使用不等号,减小猜测的时间复杂度.

获取数据库名: ?id=1’ and if(left(database(),1)=’s’ , sleep(3), 1) –+,得知数据库名的第一个字符为s.同样,一般用ascii()方法将字符转换成数字,这样可以用二分法减小时间复杂度.比如 ?id=1’ and if(((ascii(substr(database(),0,1)))>100),sleep(3),0)–+.

布尔盲注的手动操作非常繁琐,因此往往都是用脚本执行的.获取其他信息的方法类似,不再赘述.

LeetCode刷题记录

创建于

回文数

https://leetcode-cn.com/problems/palindrome-number

给出一个整数,判断它是否是回文数,121是,0是,-1不是,-121不是

第一种解法 理论上比较差的一种:转成String然后比较一下就可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public boolean isPalindrome(int x) {
if(x<0){
return false;
}

String str=Integer.toString(x);
int len=str.length();
for(int i=0;i<=len/2;i++){
if(str.charAt(i)!=str.charAt(len-1-i)){
return false;
}
}
return true;
}
}

执行用时:10 ms

内存消耗:39.1 MB

第二种解法 官方题解,把数的后面一半倒过来,和前一半比较

1
2
3
4
5
6
7
8
9
10
11
class Solution {
public boolean isPalindrome(int x) {
if(x<0||(x%10==0&&x!=0))return false;//这里,如果是10的倍数,一定也不是回文数
int re=0;
while(x>re) {//判断什么时候已经到达了一半:re比x小或者相等,就说明到了一半了
re=re*10+x%10;
x/=10;
}
return (re==x)||(re/10==x);//偶数个数字,就是相等; 奇数个数字的时候,循环结束(12321)时,re是123,x是12,而最中间那个3不会影响回文数,所以直接去掉最中间的数字3后相等也可
}
}

执行用时 :9 ms, 在所有 Java 提交中击败了99.19%的用户

内存消耗 :39.2 MB, 在所有 Java 提交中击败了5.14%的用户

奇怪的是,第二种方法没有开新的String,只用了一个int,反而内存用的多…

动态规划

创建于

动态规划(Dynamic Programming)

动态规划背后的基本思想非常简单。大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再根据子问题的解以得出原问题的解。

通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量:一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。

例题1 最大子序和

https://leetcode-cn.com/problems/maximum-subarray/submissions/

给出一个数组,求连续子数组的和的最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Solution {
public int maxSubArray(int[] nums) {
if(null==nums||0==nums.length){
return 0;
}
int res=nums[0];
int d0=0;
//初始化,最终结果为第一个元素值,第0个元素前面的连续元素最多能提供的值为0
for(int i=0;i<nums.length;i++){//遍历每个元素
if(d0>0){
d0+=nums[i];//当前元素前面的连续(n个)元素能提供的值为正,那么加上当前元素,这(n+1个)元素能提供在最大值为d0+1
}
else{
d0=nums[i];//当前元素前面的连续(n个)元素能提供的值为负(或者0),那么包含当前元素能提供的最大值就是当前元素,因为负数加上当前元素总是变小的.
}
res=Math.max(d0,res);//保存最大值
}
return res;
}
}

Linux别名alias的用法以及联想拯救者没有WiFi的解决方法

创建于
rfkill list all

发现 ideapad_wlan: Wireless LAN中的hard block 为 yes

解决方法:

sudo modprobe -r ideapad_laptop

由于这个问题出现了很多次,所以给这个命令设置一个别名

alias wifi='sudo modprobe -r ideapad_laptop'

alias用法:

alias //查看所有已经存在的别名
alias 命令='完整命令'  //设置一个别名 
unalias 命令 //移除一个别名

以后直接输入wifi 即可修复这个问题

Linux笔记2-Bash

创建于

Bash

  • 查看进程们 ps
  • -l 可以显示 详细信息

daemon(服务) 守护进程,常驻内存的程序.主要是系统的程序和网络有关的程序.

数据流重导向

标准输入  (stdin) :代码为 0 ,使用 < 或 << ;

标准输出  (stdout):代码为 1 ,使用 > 或 >> ;

标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;

一个>是覆盖写入文件,两个>>是累加写入文件,命令当有输出的时候,可以用>来把输出接住,放到后面的文件里面,比如:

ls 1>> files //1表示正确信息,2表示错误信息,这句话把ls的输出存在了files里面

cat > catfile  //此命令后,输入一些字符,按ctrl+d即可保存字符到catfile里面

<的作用: 用文件代替一个键盘输入,比如:

cat > catfile2 < catfile  //本来应该是前两个以后按键盘输入,写入catfile2,但是实际上,并不需要键盘,而是将后面的catfile的内容写到了catfile2里面

<<的作用:

cat > catfile <<"string" //输入string,即可结束输入,而不是ctrl+d,而且,最终的文件并不包含string

命令运行的判断依据: ; , &&, ||

用;把命令隔开,可以一次(并不是同时)运行好几个命令

cmd1 ; cmd2 //经过测试,这里分号前后不需要空格

cmd1执行完了马上执行cmd2

程序运行返回值是$?,利用返回值可以在命令中进行类似if else的操作,比如:

cmd1 || cmd2 //经过测试,这里前后也不需要空格

cmd1运行成功(失败是,比如某个文件不存在之类的),则cmd2就不运行了

cmd1 && cmd2

cmd1运行成功,cmd2才会运行

有多个命令连接的时候,如果有一个没有运行,那么他的上一个的返回值会接着传到后面.

管线命令 (pipe)

|

cmd1|cmd2

将cmd1的输出作为cmd2的输入,比如

ls | less

如果文件太多,就可以通过这样前后翻阅

  • 管线命令只能接收正确的输出(stdout),而错误(stderr)会被忽略

Linux的小笔记

创建于

点击这里查看鸟哥的Linux私房菜

点击上面的链接跳转查看时,建议使用鼠标中键以免难以返回


从后台启动进程,应在命令的结尾加上哪个符号 &

shell脚本 命令行 参数:

  • $0表示脚本名,$1 -$9表示后面的参数
  • $# 是传给脚本的参数个数
  • $@ 是传给脚本的所有参数的列表
  • $* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
  • $$ 是脚本运行的当前进程ID号
  • $? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

升级物理内存,相应的要提高linux服务器交换空间,以下可以扩展交换空间的操作 dd if=/dev/zero of=/mnt/sw1;swapon /mnt/sw1

将这个自定义注册项添加到一个组策略对象(GPO): 配置一个ADM模板并把模板添加到GPO

解析: ADM 文件是组策略用以描述基于注册表的策略设置在注册表中的存储位置的模板文件。ADM 文件还描述了管理员在“组策略对象编辑器”管理单元中看到的用户界面。管理员使用组策略对象编辑器创建或修改组策略对象 (GPO)。

  • 系统当前已经加载的所有文件系统 /etc/mtab
  • etc/fstab文件的作用 :记录了计算机上硬盘分区的相关信息,启动 Linux 的时候,检查分区的 fsck 命令,和挂载分区的 mount 命令,都需要 fstab 中的信息,来正确的检查和挂载硬盘。

top查看cpu使用

df查看磁盘使用

rsync (远程)拷贝文件用的

wget 下载文件

scp 复制远程文件

将执行的ls命令的输出结果保存在当前目录下文件output.ls中,以供日后进行分析和使用,但要求不覆盖原文件的内容,他应该使用的命令是

  • ls>>output.ls
  • |(没有竖线) > 输出重定向到一个文件或设备 覆盖原来的文件
  • |>! 输出重定向到一个文件或设备 强制覆盖原来的文件
  • |>> 输出重定向到一个文件或设备 追加原来的文件
  • |< 输入重定向到一个程序

Linux笔记

创建于

点击这里查看鸟哥的Linux私房菜

点击上面的链接跳转查看时,建议使用鼠标中键以免难以返回


ls -al a:所有;l:详细信息

man: 显示用法

权限

  • chgrp: change group;
  • chown:change owner;
  • chmod:改变权限 三个数字分别为 owner group others r:4 w:2 x:1

-R :递归,修改子目录所有的文件

  • x对于文件来说是可执行,对目录来说是是否可切换到这个目录(cd命令)r可以读取列表(ls)
  • 目录属于用户,拥有744权限,目录下的文件对于用户来说权限都是7

建立空档案: touch 也可以用于修改文件的时间

Linux档案类型

  • 正规:- 纯文本,二进制,数据格式文件(data)
  • 目录:d
  • 联结 l link,类似于快捷方式
  • 区块设备 block,b,硬盘软盘都是
  • 字符设备文件 键盘鼠标 character,c
  • 资料接口 socket ;
  • 数据输送文件 FIFO,pipe, p ;脚本的扩展名是sh

路径:

  • 绝对路径: 开头是/
  • 相对路径:开头不是/
  • ./表示本目录
  • ../表示上层目录
  • -表示上个工作目录
  • ~home目录
  • 指令 cd(Change Directory)
  • mkdir -P忽视错误 -m777指定权限
  • pwd Print Working Directory
  • rmdir删除空目录

ls:

  • -a 全部文件
  • t 时间排序
  • S 文件大小排序
  • r 倒序
  • R 递归
  • -l 详细信息

cat Concatenate (连续查看一个文件)

  • -n,行号;-b,空行不占行号
  • tac倒着输出行
  • -v,显示看不见的字符

chattr (配置文件隐藏属性)

  • 选项与参数:
  •  +   :添加某一个特殊参数,其他原本存在参数则不动.
    
  •  -   :移除某一个特殊参数,其他原本存在参数则不动。
    
  •  =   :配置一定,且仅有后面接的参数
    
  • i 不能被删除,增删,改名
  • a 只能添加数据

lsattr (显示文件隐藏属性)

file 观察文件类型


搜索文件

whereis 定位某个命令 的二进制文件、源码和帮助页文件。

locate 定位的是文件.用的是数据库,默认每天更新一次,可以手动更新,命令是updatedb (我自己测试需要sudo)

find 定位文件,搜索指定目录

  • +4代表大於等於5天前的档名:ex> find /var -mtime +4
  • -4代表小於等於4天内的文件档名:ex> find /var -mtime -4
  • 4则是代表4-5那一天的文件档名:ex> find /var -mtime 4

vim

vim的操作特别多,我一般用IDE,只记录几个

  • nG 去第n行
  • gg 去第一行
  • / ? word 向下或向上查找word字符串
  • n N 向下或向上接着查找刚才的字符串
  • :n1,n2s/word1/word2/g n1 与 n2 为数字。在第 n1 与 n2 行之间寻找 word1 这个字符串,并将该字符串取代为 word2!举例来说,在 100 到 200 行之间搜寻 vbird 并取代为 VBIRD 则:
    『:100,200s/vbird/VBIRD/g』。(常用)
  • 上面的g改为gc,每个替换之前会要求用户确认
  • yy 复制一行
  • p 粘贴
  • u undo,撤销
  • Ctrl+r 重做

  • :w [filename] 将编辑的数据储存成另一个档案(类似另存新档)
  • :r [filename]在编辑的数据中,读入另一个档案的数据。亦即将 『filename』 这个档案内容加到游标所在行后面

  • ctrl+z 暂存并离开

bash


腾讯面试刷题

创建于

###压缩算法-腾讯2020第一次校园招聘后台综合笔试

小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么?

输入描述:

输入第一行包含一个字符串s,代表压缩后的字符串。

S的长度<=1000;

S仅包含大写字母、[、]、|;

解压后的字符串长度不超过100000;

压缩递归层数不超过10层;

输出描述:

输出一个字符串,代表解压后的字符串。

示例1

输入

HG[3|B[2|CA]]F

输出

HGBCACABCACABCACAF

说明

HG[3|B[2|CA]]F−>HG[3|BCACA]F−>HGBCACABCACABCACAF

点击这里查看CSDN解法

我的解法:每次替换一对[];java的replace是替换字符串并且不改变原有字符串,所以替换务必再赋值,replaceAll是正则表达式替换,因此应该使用replace;subString方法左闭右开

```java

package com.company;
import java.util.*;
public class Main {

public static void main(String[] args) {


    Scanner scanner=new Scanner(System.in);
    String string=new String();
    string = scanner.nextLine();
    for(int i=0;i<string.length();i++){
        if(']'==string.charAt(i)){      //  i是]
            int j=i;
            int k=0;
            while('['!=string.charAt(j)){
                if('|'==string.charAt(j)){
                    k=j;                //  k是|
                }
                j--;                    //j 是[,不是[的上一个
            }
            int len=Integer.parseInt(string.substring(j+1,k));

            //System.out.println(len);

            StringBuilder stringBuilder=new StringBuilder();
            for(int i2=0;i2<len;i2++){
                stringBuilder.append(string.substring(k+1,i));
            }

            //System.out.println(stringBuilder.toString());
            //System.out.println(string.substring(j,i+1));

            string=string.replace(string.substring(j,i+1),stringBuilder.toString());
            //替换务必赋值

            //System.out.println(string);

            i=j;
        }

    }
    System.out.println(string);
    //System.out.println(sol.numWays(2));
    //System.out.println("%2");
    //int a=1294967299;
    //System.out.println(sol.myAtoi("-321.14"));
    // write your code her

}

}

```java

剑指offer刷题记录

创建于

点击这里查看LeetCodeCN剑指offer官网题目列表

点击上面的链接跳转查看题解等时,建议使用鼠标中键以免难以返回


0.0.1. 面试题03数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public int findRepeatNumber(int[] nums) {
for (int i = 0; i < nums.length; i++) {
while (nums[i] != i) {
if (nums[i] == nums[nums[i]])
return nums[i];
int temp = nums[i];
nums[i] = nums[temp];
nums[temp] = temp;
}
}
return -1;
}
}

0.0.2. 面试题04二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix==null||matrix.length==0||matrix[0].length==0){
return false;
}
int n=matrix.length-1;
int m=matrix[0].length-1;
if((m+n)==-2){
return false;
}
int x=0;
int y=n;
while(matrix[y][x]!=target){

if(matrix[y][x]>target){
y--;
}
else{
x++;
}
if(!(x<=m&&y>=0)){
return false;
}
}
return true;
}
}

0.0.3. 面试题04二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if(matrix==null||matrix.length==0||matrix[0].length==0){
return false;
}
int n=matrix.length-1;
int m=matrix[0].length-1;
if((m+n)==-2){
return false;
}
int x=0;
int y=n;
while(matrix[y][x]!=target){

if(matrix[y][x]>target){
y--;
}
else{
x++;
}
if(!(x<=m&&y>=0)){
return false;
}
}
return true;
}
}

0.0.4. 面试题05替换空格

请实现一个函数,把字符串 s 中的每个空格替换成”%20”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public String replaceSpace(String s) {
if(s==null||s.isEmpty()){
return s;
}
StringBuilder res=new StringBuilder();
for(int i=0;i<s.length();i++){
if(s.charAt(i)==' '){
res.append("%20");
}
else{
res.append(s.charAt(i));
}
}
return res.toString();
}
}

0.0.5. 面试题06. 从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {

Stack<Integer> stack=new Stack<>();
int num=0;
for(; head !=null;head=head.next) {
stack.push(head.val);
num++;
}
int res[] =new int[num];
for(int i=0;i<num;i++){
res[i]=stack.pop();
}
return res;
}
}

0.0.6. 面试题09. 用两个栈实现队列

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class CQueue {
private Stack<Integer> s1;
private Stack<Integer> s2;
public CQueue() {
s1=new Stack<>();
s2=new Stack<>();
}

public void appendTail(int value) {
s1.push(value);
}

public int deleteHead() {
if(s2.isEmpty()){
while(!s1.isEmpty()){
s2.push(s1.pop());
}
}
if(!s2.isEmpty())
return s2.pop();
else{
return -1;
}
}
}

0.0.7. 面试题10- I. 斐波那契数列

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:

F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int fib(int n) {
if(n==0||n==1){
return n;
}
int a=0,b=1;
int temp=0;
while(n>=2){
temp=(a+b)%1000000007;
a=b;
b=temp;
n--;
}
return temp;

}
}

0.0.8. 面试题10- II. 青蛙跳台阶问题

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public int numWays(int n) {
if(n==0||n==1){
return 1;
}
int a=1,b=1;
int temp=0;
while(n>=2){
temp=(a+b)%1000000007;
a=b;
b=temp;
n--;
}
return temp;

}
}

0.0.9. 面试题15. 二进制中1的个数

请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-jin-zhi-zhong-1de-ge-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1
2
3
4
5
6
7
8
9
10
11
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
int res = 0;
while(n != 0) {
res += n & 1;
n >>>= 1;
}
return res;
}
}

0.0.10. 面试题24. 反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode pre=null,next=null;
while (head!=null){
next=head.next;
head.next=pre;
pre=head;
head=next;
}
return pre;
}
}

0.0.11. 面试题41. 数据流中的中位数

如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。

例如,

[2,3,4] 的中位数是 3

[2,3] 的中位数是 (2 + 3) / 2 = 2.5

设计一个支持以下两种操作的数据结构:

void addNum(int num) - 从数据流中添加一个整数到数据结构中。
double findMedian() - 返回目前所有元素的中位数。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class MedianFinder {

/** initialize your data structure here. */
private PriorityQueue<Integer> max;
private PriorityQueue<Integer> min;
private boolean turn;
public MedianFinder() {
turn=true;
min =new PriorityQueue<Integer>();
max =new PriorityQueue<Integer>(11, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
}

public void addNum(int num) {
if(max.isEmpty()){
max.add(num);
return ;
}
if(min.size()==max.size()){//两个一样多,添加到第一个;或者添加到第二个,并移动一个元素到第一个
if(num<min.peek()){//比第二个的小
max.add(num);
}
else{
max.add(min.poll());
min.add(num);
}
}
else{//第一个比第二个多
if(num>max.peek()){//比第一个的大,添加到第二个
min.add(num);
}
else{//比第一个的小,添加到第一个,移动一个元素到第二个
max.add(num);
min.add(max.poll());
}
}
}

public double findMedian() {
if(max.isEmpty()){
return 0.0;
}
if(((max.size()+min.size())%2)==1){
return max.peek();
}
else{
return (max.peek()+min.peek())/2.0;
}
}
}

0.0.12. 面试题36. 二叉搜索树与双向链表

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。

https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/

1
一个月前的提交记录不见了

0.1.

1