51.构建乘积数组

题目描述

给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。

思路:


B[i]的值可以看做如图矩阵中每行的乘积,下三角用连称可以很容易求得,上三角从上向下也是连乘,所以我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律把另一部分也乘进去

package com.matajie;/*** 51.构建乘积数组* 题目描述* 给定一个数组A[0,1,...,n-1],* 请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。* 不能使用除法。** 我的程序才不会有bug!* author:年仅18岁的天才少年程序员丶mata杰**/
public class Multiply {public int[] multiply(int[] A) {int length = A.length;int[] B = new int[length];if(length != 0){B[0] = 1;//计算下三角连乘for(int i = 1;i<length;i++){B[i] = B[i-1] *A[i-1];}int temp = 1;//计算上三角连乘for(int j = length - 2;j >= 0;j--){temp *= A[j+1];B[j] *= temp;}}return B;}
}

52.正则表达式匹配

题目描述

请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配

思路:

当模式中第二个字符不是"*"时:

  1. 如果字符串第一个字符和模式中的第一个字符相匹配,那么字符串和模式都后移一个字符,然后匹配剩余的.
  2. 如果字符串第一个字符和模式中的第一个字符不匹配,直接返回false.

而当模式中的第二个字符是"*"时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配.如果字符串第一个字符跟模式第一个字符匹配,可以有三种匹配模式:

  1. 模式后移2字符,相当于X被忽略(例如aaaba)
  2. 字符串后移一字符,模式后移2字符(aaaa*a)
  3. 字符串后移1字符,模式不变,即继续匹配字符下一位,因为可以匹配多位.(例如baab bab,*前可能有多个a)
    再观察一下,我们发现情况2可以被情况1和情况3包含,执行一次情况3,在执行一次情况1,就相当于情况2.
package com.matajie;/*** 52.正则表达式匹配* 题目描述** 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,* 而'*'表示它前面的字符可以出现任意次(包含0次)。* 在本题中,匹配是指字符串的所有字符匹配整个模式。* 例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配** 我的程序才不会有bug!* author:年仅18岁的天才少年程序员丶mata杰**/
public class Match {public boolean match(char[] str, char[] pattern){if(str == null || pattern == null) return false;int strIndex = 0;int patterIndex = 0;return matchCore(str,strIndex,pattern,patterIndex);}public boolean matchCore(char[] str,int strIndex,char[] pattern,int patternIndex){//有效性检验:str到尾,pattern到尾,匹配成功if(strIndex == str.length && patternIndex == pattern.length) return true;//pattern先到尾,匹配失败if(strIndex != str.length && patternIndex == pattern.length) return false;//模式第二个是*,且字符串第一个跟模式第一个匹配,分2种匹配模式if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {if((strIndex != str.length && pattern[patternIndex] == str[strIndex])|| (pattern[patternIndex] == '.' && strIndex != str.length)){return matchCore(str,strIndex,pattern,patternIndex+2)//模式后移2,视为X*匹配0个字符|| matchCore(str,strIndex+1,pattern,patternIndex);//*匹配一个,再匹配str中的下一个.}else {return matchCore(str,strIndex,pattern,patternIndex+2);}}//模式第二个不是*,且字符串第一个跟模式第一个匹配,则都后移1位,否则直接返回false.if((strIndex != str.length && pattern[patternIndex] == str[strIndex])||(pattern[patternIndex] == '.' && strIndex != str.length)){return matchCore(str,strIndex+1,pattern,patternIndex+1);}return false;}
}

53.表示数值的字符串(正则表达式匹配)

题目描述

请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。例如,字符串"+100",“5e2”,"-123",“3.1416"和”-1E-16"都表示数值。 但是"12e",“1a3.14”,“1.2.3”,"±5"和"12e+4.3"都不是。

思路一:

package com.matajie;/*** 53.表示数值的字符串(正则表达式匹配)* 题目描述*** 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。* 例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。* 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。** 我的程序才不会有bug!* author:年仅18岁的天才少年程序员丶mata杰**/
public class IsNumeric {public boolean isNumeric(char[] str) {//标记符号,小数点,e是否出现过boolean sign = false;boolean decimal = false;boolean hsaE = false;for(int i = 0;i<str.length;i++){if(str[i] == 'e' || str[i] == 'E') {if(i == str.length-1)return false;//e后面一定要接数字if(hsaE) return false;//不能同时存在两个ehsaE = true;} else if (str[i] == '+' || str[i] == '-') {//第二次出现+-符号,则必须紧接在e后面if(sign&&str[i-1]!='e' && str[i-1] != 'E')return false;//第一次出现+-符号,且不是在字符串开头,则也必须紧接在e之后if(!sign && i>0 && str[i-1] !='e' &&str[i-1] !='E')return false;sign =true;}else if(str[i] == '.'){//e后面不能接小数点,小数点不能出现两次if( hsaE || decimal) return false;decimal = true;}else if(str[i] < '0' ||str[i] > '9'){return false;}}return true;}
}

思路二:正则表达式

package com.matajie;/*** 53.表示数值的字符串(正则表达式匹配)* 题目描述*** 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。* 例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。* 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。** 我的程序才不会有bug!* author:年仅18岁的天才少年程序员丶mata杰**/
public class IsNumeric {public boolean isNumeric(char[] str) {String string = String.valueOf(str);return string.matches("[\\+\\-]?\\d*(\\.\\d+)?([eE][\\+\\-]?\\d+)?");}
}

[\+\-]? : 正或负号出现与否
\d* : 整数部分是否出现,如-3.14或3.14均符合
\d*(\.\d+)? : 如果出现小数点,那么小数点后面必须有数字,否则一起不出现
([eE][\+\-]?\d+)? : 如果存在指数部分,那么e或E肯定出现,+或-可以不出现,紧接着必须跟着整数,或者整个部分都不出现

思路三: 编译原理自动机

54.字符流中第一个不重复的字符

题目描述

请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。

思路:

使用一个HashMap来统计字符出现的次数,同时用一个ArrayList来记录输入流,每次返回第一个出现一次的字符都是在这个ArrayList(输入流)中的字符作为key去map中查找.

package com.matajie;import java.util.ArrayList;
import java.util.HashMap;/*** 54.字符流中第一个不重复的字符* 题目描述** 请实现一个函数用来找出字符流中第一个只出现一次的字符。* 例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。* 当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。** 我的程序才不会有bug!* author:年仅18岁的天才少年程序员丶mata杰**/
public class FirstAppearingOnce {HashMap<Character,Integer> map = new HashMap<>();ArrayList<Character> list = new ArrayList<>();public void Insert(char ch){if(map.containsKey(ch)){map.put(ch,map.get(ch)+1);}else {map.put(ch,1);}list.add(ch);}public char FirstAppearingOnce(){
char c = '#';
for(char key : list){if(map.get(key) == 1){c = key;break;}
}
return c;}
}

55.链表中环的入口节点

题目描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。

思路一:


假设X为环前面的路程(绿),a为环入口到相遇点的路程(蓝)c为环的长度(蓝+紫)
当快慢指针相遇时:
此时慢指针走的路程为Sslow = X + m * c + a.
快指针走的路程为Sfast = X + n * c + a.
2Sslow = Sfast.
2*(X + mc +a) = (X + nc + a)
=>X = (n-2*m)c-a = (n-2m-1)c+c-a(因为m = 0,n>0,慢指针是不可能绕圈的,走不完一圈就会被追上,所以n-2m-1 >= 0).
即环前面的路程= 数个环的长度 + c-a
c-a是什么?
这是相遇点后,换后面部分的路程(紫),所以我们可以让一个指针从起点A开始走,让一个指针从相遇点B开始继续往后走,2个指针速度相同,那么当从原点的指针走到环入口点时(此时当好走了X),从相遇点开始走的那个指针也一定刚好到达环入口点,所以2者会相遇,且恰好相遇在环的入口点.
由上述证明可这样解:

package com.matajie;/*** 55.链表中环的入口节点*  题目描述** 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。** 我的程序才不会有bug!* author:年仅18岁的天才少年程序员丶mata杰**/
public class EntryNodeOfLoop {public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}}public ListNode EntryNodeOfLoop(ListNode pHead){if(pHead == null || pHead.next == null || pHead.next.next == null)return null;ListNode fast = pHead.next.next;ListNode slow = pHead.next;//先判断有没有环while (fast != slow){if(fast.next != null && fast.next.next != null){fast = fast.next.next;slow = slow.next;}else {return null;}}//循环出来说明有环,此时fast == slowfast = pHead;while (fast != slow){fast = fast.next;slow = slow.next;}return slow;}
}

思路二:

set不能有重复元素(比较的是ListNode这个指针是否指向同一个对象,地向的地址是否相同,和所指对象无关)

package com.matajie;import java.util.HashSet;/*** 55.链表中环的入口节点*  题目描述** 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。** 我的程序才不会有bug!* author:年仅18岁的天才少年程序员丶mata杰**/
public class EntryNodeOfLoop {public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}}public ListNode EntryNodeOfLoop(ListNode pHead){HashSet<ListNode> set = new HashSet<>();while (pHead != null){if(!set.add(pHead)){return pHead;}pHead = pHead.next;}return null;}
}

[Java]剑指offer51-55题_day11相关推荐

  1. java统计一个字符串中每个字符出现的次数_剑指offer算法题054:字符流中第一个不重复的字符...

    推荐阅读:宇宙条的工作总结:一年前还在面试找工作,一年后在面试找工作的学弟学妹们:第一次当面试官的经历分享小编在求职找找工作期间剑指offer上的算法题刷了很多遍,并且每道题小编当时都总结了一种最适合 ...

  2. Day5.牛客网剑指offer 67题之43-54题(java代码)

    文章目录 Day5.牛客网剑指offer 67题之43-54题 43.左旋转字符串 44.翻转单词顺序列 45.扑克牌顺序 46.孩子们的游戏 47.求1+2+...+n 48.不用加减乘除做加法 4 ...

  3. 剑指offer编程题(JAVA实现)——第35题:数组中的逆序对

    github https://github.com/JasonZhangCauc/JZOffer 剑指offer编程题(JAVA实现)--第35题:数组中的逆序对 题目描述 在数组中的两个数字,如果前 ...

  4. 剑指offer编程题(JAVA实现)——第38题:二叉树的深度

    github https://github.com/JasonZhangCauc/JZOffer 剑指offer编程题(JAVA实现)--第38题:二叉树的深度 题目描述 输入一棵二叉树,求该树的深度 ...

  5. 剑指offer刷题记录 python3 Java

    剑指offer刷题记录 python3 Java 剑指 Offer 09. 用两个栈实现队列 剑指 Offer 10- I. 斐波那契数列 剑指 Offer 03. 数组中重复的数字 [★]剑指 Of ...

  6. 剑指Offer-Java刷题个人题解与总结

    刷题 Java刷题技巧 Java输入输出问题 Scanner sc=new Scanner(System.in); 输入一行字符串:sc.nextLine() 输入一个基本类型:sc.nextInt. ...

  7. 剑指offer(60-67题)详解

    文章目录 60 把二叉树打印成多行 61 序列化二叉树 62 二叉搜索树第K个节点 63 数据流中的中位数 64 滑动窗口的最大值 65 矩阵中的路径 66 机器人的运动范围 67 剪绳子 欢迎关注个 ...

  8. 剑指offer(34-40题)详解

    文章目录 34 第一个只出现一次的字符 35 数组中的逆序数 36 两个链表的第一个公共节点 37 数字在排序数组中出现的次数 38 二叉树的深度 39 平衡二叉树 40 数组中只出现一次的数字 欢迎 ...

  9. 剑指offer(26-33题)详解

    文章目录 26 二叉搜索树与双向链表 27 字符串的排列 28 数字中出现次数超过一半的数字(待优化)★ 29 最小的K个数 30 连续子数组最大和 31 整数中1出现的次数 32 把数组排成最小的数 ...

  10. 剑指offer(11-25题)详解

    文章目录 11 二进制种1的个数★ 12 数值的正数次方 13 调整数组顺序使奇数位于偶数前面 14 链表中倒数第K个节点 15 反转链表 16 合并两个排序的链表 17 树的子结构 18 二叉树的镜 ...

最新文章

  1. 各种Optimizer梯度下降优化算法回顾和总结
  2. 12864液晶——读写、划点、划线、汉字、32*16的字符
  3. datagrid后台分页js.js
  4. Hello World(本博客启程篇)
  5. ov5640帧率配置_逃离塔科夫怎么提升帧率 帧率优化建议_单机游戏_游戏攻略
  6. php curl header 下载_PHP通过curl下载文件到浏览器
  7. *学生管理系统java面向对象版本
  8. 【Ubuntu18.04安装搜狗中文输入法】
  9. Unity中通过ButtonClicked更换GameOgject纹理图片
  10. 郑码输入法 字根记忆表 一般根变通处理
  11. Error occurred when installing package 'qcloud_cos'
  12. 如何使用CANoe和CANalyzer中的Diagnostics/ISO TP
  13. 谷歌服务组件安装简介
  14. 山峰和山谷 Ridges and Valleys
  15. 135编辑器生成html,135编辑器如何使用动态样式
  16. 企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等
  17. [Python图像处理] 合成微缩效果
  18. java 代码 二义性是什么_Java接口默认方法带来的问题分析【二义性问题】
  19. 用 pc 抓取 vlan tag 的数据包
  20. J-Link下载烧录提示Failed to read back RAMCode for verification

热门文章

  1. 2021上海L Three,Three,Three(一般图匹配)
  2. 猿团项目实战-仿途牛旅行APP免费视频课程
  3. Newtonsoft.Json类库学习
  4. 1.1XAF框架开发视频教程-简单的订单管理实现过程,视频,提纲,及教程源码
  5. 公共区域U盘窃取数据
  6. 关于在《python编程从入门到实践》书中练习“外星人大战”报错“AttributeError: ‘AlienInvasion‘ object has no attribute ‘blit‘”
  7. OmniPlan Pro 4:项目流程管理工具
  8. MySQL中修改密码及访问限制
  9. 编译原理期末复习—第一章概论
  10. 杭电OJ 1047(C++)