16.反转链表

输入一个链表,反转链表后,输出新链表的表头。

从前往后,依次将当前节点的next指向前结点。用多个变量存储当前节点,下一节点,前结点。


public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null)
return null;
//从头开始,依次将节点的next指向前一个结点
ListNode prev=null;
ListNode cur=head;
ListNode follow=null;
while(cur.next!=null){
follow=cur.next;//获得当前结点的下个节点
cur.next=prev;//将当前节点的next指向前一个结点
prev=cur;//保存当前结点作为前结点
cur=follow;
}
cur.next=prev;
return cur;
}
}

17.合并两个排序的链表

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

基本:遍历两链表,当l2中元素小于l1时,将其加入l1,直到末尾。或者新建一个链表,将小的依次加入该链表


1.暴力:

/*添加至list1*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
//结果要求是单调递增
//错误输入的判断
if(list1==null && list2 ==null)
return null;
if(list1== null)
return list2;
if(list2==null)
return list1;
ListNode p1=list1;
ListNode p2=list2;
ListNode temp1=null;//暂存两链表的结点
ListNode temp2=null;
//依次从链表头开始判断
while(p1!=null && p2!=null ){
while(p1!=null && p1.val<p2.val){//当l1的结点小于l2时,将l1结点右移
temp1=p1;//记录当前结点,便于后续插入
p1=p1.next;
}//直到p1.val >= p2.val或p1.next==null
if(p1==null){//若l1已到末尾,则将l2的结点接到l1末尾后
temp1.next=p2;
return list1;
}
temp2=new ListNode(p2.val);//list2的结点移到list1
temp2.next=p1;
if(temp1!=null)//判断是否是添加到l1的头部
temp1.next=temp2;
else{//是则让list1头节点变为temp2
list1=temp2;
}
p1=temp2;//该结点一定比l2的下一节点小,所以temp1下一步一定会切换
if(p2.next==null)//如果l2遍历完毕
break;
p2=p2.next;//p2右移
}
return list1;
}
}

2.递归:

/*相当于一个新链表*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
//结果要求是单调递增
//错误输入的判断
if(list1==null && list2 ==null)
return null;
if(list1== null)
return list2;
if(list2==null)
return list1;
//递归
if(list1.val <=list2.val){
list1.next=Merge(list1.next,list2);
return list1;
}else{
list2.next=Merge(list1,list2.next);
return list2;
}
}
}

3.新建链表存储:

public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
//新建一个头节点,用来存合并的链表。
ListNode head=new ListNode(-1);
head.next=null;
ListNode root=head;
while(list1!=null && list2!=null){
if(list1.val<list2.val){
head.next=list1;
head=list1;
list1=list1.next;
}else{
head.next=list2;
head=list2;
list2=list2.next;
}
}
//把未结束的链表连接到合并后的链表尾部
if(list1!=null){
head.next=list1;
}
if(list2!=null){
head.next=list2;
}
return root.next;
}
}

18.树的子结构

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

先判断A中根节点是否等于B根节点,相等则对两者左右子树进行遍历判断是否相等;

若根节点不等,则从A的左右子树中寻找等于B中根节点的节点,然后判断。

递归


递归:

public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root1 ==null || root2 == null)//输入判断
return false;
boolean flag=false;
//查看2的前序和中序遍历是否属于1
if (root1.val == root2.val){//当A的根结点等于B的根节点时,对其子树进行遍历判断(递归)
flag=judgeSub(root1,root2);
}
if(!flag)//当A的根节点不等于B的根节点时,从根节点的左子树中查找相等的节点
flag=HasSubtree(root1.left,root2);
if(!flag)//从根节点的右子树中查找相等的节点
flag=HasSubtree(root1.right,root2);
return flag;
} //根节点相等时,判断其结构是否相等
public boolean judgeSub(TreeNode root1,TreeNode root2){
if(root2==null)//若B节点为空,则证明该节点前结构属于A,因为前面的已证过相等,不然不会走到该步
return true;
if(root1==null)//若A节点为空,则两者结构不等
return false;
if(root1.val != root2.val)
return false;
return judgeSub(root1.left,root2.left) && judgeSub(root1.right,root2.right);//递归判断左右子树是否相等
}
}

19.二叉树的镜像

操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:

二叉树的镜像定义:
源二叉树
8
/ \
6 10
/ \ / \
5 7 9 11
镜像二叉树
8
/ \
10 6
/ \ / \
11 9 7 5

递归处理左右子树

递归:

public class Solution {
public void Mirror(TreeNode root) {
if(root!=null){
//根节点不变,左右子树交换位置
//递归
if(root.left!=null ){//若根节点左右子树非空,则将左右子树进行翻转
Mirror(root.left);
}
if(root.right!=null)
Mirror(root.right);
TreeNode temp=root.left;
root.left=root.right;
root.right=temp;
}
}
}

20.顺时针打印矩阵

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10。

找到每次遍历的起始点,然后以此进行判断每次遍历的边界。(每次遍历前一定要判断前置条件)


1.暴力:

import java.util.ArrayList;
public class Solution {
private ArrayList<Integer> result=new ArrayList<>();
public ArrayList<Integer> printMatrix(int [][] matrix) {
if(matrix==null || matrix.length==0)
return null;
int rows=matrix.length;
int cols=matrix[0].length;
int start=0;
//找出每一圈的起始点。即左上角的点,(0,0) (1,1)等
while(rows>start*2 && cols>start*2){
int endCol=cols-1-start;//该次遍历时最右边列的坐标
int endRow=rows-1-start;//该次遍历时最下边行的坐标 for(int i=start;i<=endCol;++i){//打印第一行
result.add(matrix[start][i]);
}
if(start<endRow){//满足才有一列可以打印,否则一行直接打印完毕
for(int i=start+1;i<=endRow;++i){//打印最后一列
result.add(matrix[i][endCol]);
}
}
if(start<endCol && start<endRow){//满足才有最后一行可以打印
for(int i=endCol-1;i>=start;--i){//打印最后一行
result.add(matrix[endRow][i]);
}
}
if(start<endCol && start< endRow-1){//满足时才会在最后一行打印完毕后仍有上面的行
for(int i=endRow-1;i>start;--i){//打印第一列
result.add(matrix[i][start]);
}
}
start++;
}
return result;
} }

如有错误,欢迎指正

剑指Offer系列之题16~题20的更多相关文章

  1. 剑指offer——python【第16题】合并两个有序链表

    题目描述 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2->4, 1->3->4 输出:1->1-& ...

  2. 干货 | 剑指offer系列文章汇总

    下面是名企面试中经常会出现的面试题目,大家可以戳相应的题目查看题目细节,其答案会在紧接着的后一篇中出现  剑指offer系列  始 剑指offer—灯管问题(1)  剑指offer—10人电梯(2)  ...

  3. 剑指offer——python【第54题】字符流中第一个不重复的字符

    题目描述 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g".当从该字符流中读出 ...

  4. 7、斐波那契数列、跳台阶、变态跳台阶、矩形覆盖------------>剑指offer系列

    题目:斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). f(n) = f(n-1) + f(n-2) 基本思路 这道题在剑指offe ...

  5. 剑指Offer系列之题1~题5

    目录 1.二维数组的查找 2.替换空格 3.从尾到头打印链表 4.链表中环的入口节点 5.重建二叉树 写在前面:本随笔中包含五道题:题目描述,题目思路以及对应解法. 1.二维数组的查找 在一个二维数组 ...

  6. 剑指offer——python【第60题】把二叉树打印成多行

    题目描述 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行.#类似于二维列表[[1,2],[4,5]] 解题思路 其实这倒题和其他类似的题有所区别,这里是分层打印,把每层的节点值放在同一 ...

  7. 剑指offer——python【第28题】数组 中出现次数超过一半的数字

    题目描述 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2. ...

  8. 《剑指offer》第二十六题(树的子结构)

    // 面试题26:树的子结构 // 题目:输入两棵二叉树A和B,判断B是不是A的子结构. #include <iostream> struct BinaryTreeNode { doubl ...

  9. 剑指offer——python【第23题】二叉搜索树的后序遍历序列

    题目描述 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 解题思路 首先要清楚,这道题不是让你去判断一个给定 ...

随机推荐

  1. Mysql(Mariadb)数据库之Information Schema 库中GLOBAL_VARIABLES表 and SESSION_VARIABLES 表分析

    Information Schema GLOBAL_VARIABLES and SESSION_VARIABLES Tables The Information Schema GLOBAL_VARIA ...

  2. JAVAEE学习day05学习,数组

    容器及元素的概念 容器:是将多个数据存储到一起 元素:每个数据称为该容器的元素 数组的概念 数组:数组是长度固定,存储数据的容器,保证多个数据的类型要一致 数组定义格式及其描述 动态定义: 数据类型 ...

  3. 数据库开发 Oracle与mysql间的批量处理接口 SSIS+存储过程实现

    公司目前不同的业务系统用了不同的数据库,涉及到oracle.mysql.sqlserver.而一些核心的业务在mysql中,所以平时经常要把oracle.sqlserver中的数据插入到mysql中. ...

  4. mybatis探究之延迟加载和缓存

    mybatis探究之延迟加载和缓存 一.什么是延迟加载 1.延迟加载的概念 在mybatis进行多表查询时,并非所有的查询都需要立即进行.例如在查询带有账户信息的用户信息时,我们们并不需要总是在加载用 ...

  5. javascript中怎么判断两个数据类型相等

    在 JavaScript 中,判断一个变量的类型尝尝会用 typeof 运算符,在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "obj ...

  6. 深入理解Java内存模型(摘)

    --摘自 周志明<深入理解Java虚拟机> 转自 https://www.jianshu.com/p/15106e9c4bf3 深入理解Java内存模型(摘) java内存模型(Java ...

  7. 我用STM32MP1做了个疫情监控平台4—功能完善界面重新设计

    目录 前言 界面展示 新增功能 API 接口说明 多个接口数据的获取和解析 FontAwesome字体图标库的使用 代码下载 系列教程 @ 前言 之前我用STM32MP1和Qt实现了疫情监控平台,系列 ...

  8. 9. selenium+request方式的cookie绕过

    1. 首先确认POST请求的content-type类型 2. 查看cookies数据 3. 找到对应的headers数据 4. 如果是application/json,传入的json数据需要时jso ...

  9. gRPC(2):客户端创建和调用原理

    1. gRPC 客户端创建流程 1.1 背景 gRPC 是在 HTTP/2 之上实现的 RPC 框架,HTTP/2 是第 7 层(应用层)协议,它运行在 TCP(第 4 层 - 传输层)协议之上,相比 ...

  10. pytorch tensor的索引与切片

    切片方式与numpy是类似. * a[:2, :1, :, :], * 可以用-1索引. * ::2,表示所有数据,间隔为2,即 start:end:step. *  a.index_select(1 ...