51、数组中重复的数

题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。

思路1:排序,时间复杂度O(NlogN)

思路2:Hash表,时间和空间复杂度都是O(N)

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
public class Solution {boolean duplicate(int numbers[],int length,int [] duplication) {HashMap<Integer, Integer> countMap = new HashMap<Integer, Integer>();if(length < 2||numbers==null){return false;}int j = 1;for(int i = 0;i < length;i++){if(countMap.get(numbers[i]) == null){j = 1;countMap.put(numbers[i], j);}else{j = countMap.get(numbers[i]);j++;countMap.put(numbers[i], j);}}Iterator iter = countMap.entrySet().iterator();while(iter.hasNext()){Entry<Integer, Integer> entry = (Entry<Integer, Integer>) iter.next();Integer key = entry.getKey();Integer val = countMap.get(key);if(val > 1){duplication[0] = key;return true;}}return false;}
}复制代码

思路3:用Set集合,因为Set集合不允许有重复的,时间和空间复杂度都是O(N)

import java.util.Set;
import java.util.HashSet;
public class Solution {boolean duplicate(int numbers[], int length, int[] duplication) {if(length < 2||numbers==null){return false;}Set<Integer> ss = new HashSet<Integer>();for (int i = 0; i < numbers.length; i++) {if (ss.contains(numbers[i])) {duplication[0] = numbers[i];return true;} else {ss.add(numbers[i]);}}return false;}
}
复制代码

思路4better:时间复杂度O(N),所有操作都是在输入数组上进行,所以不需要分配额外空间,空间复杂度为O(1)

[图片上传失败...(image-c952f5-1558756468475)]

public class Solution {public boolean duplicate(int numbers[],int length,int [] duplication) {if(numbers==null||length<0)return false;for(int i = 0;i < length; i++){if(numbers[i]<0||numbers[i]>length-1)return false;}for(int i = 0;i< length;i++){while(numbers[i]!=i){if(numbers[i]==numbers[numbers[i]]){duplication[0] = numbers[i];return true;}else{//没有找到,然后则交换,使该数到正确的位置去swap(numbers,i,numbers[i]);}}}return false;}//交换二数private void swap(int[]a, int i, int j){int temp = a[i];a[i] = a[j];a[j] = temp;}
}
复制代码

52、构建乘积数组

题目描述 给定一个数组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]。不能使用除法。

思路:1.计算前i - 1个元素的乘积,及后N - i个元素的乘积分别保存在两个数组中

[图片上传失败...(image-d5e569-1558756468476)]

import java.util.ArrayList;
public class Solution {public int[] multiply(int[] A) {int len = A.length;int forword[] = new int[len];int backword[] = new int[len];int B[] = new int[len];forword[0] = 1;backword[0] = 1;for(int i = 1;i < len; i++){forword[i] = A[i - 1]*forword[i-1];backword[i] = A[len - i]*backword[i - 1];}for(int i = 0; i < len; i++){B[i] = forword[i] * backword[len - i -1];}return B;}
}
复制代码

53、正则表达式匹配

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

public class Solution {public boolean match(char[] str, char[] pattern) {if (str == null || pattern == null) {return false;}int strIndex = 0;int patternIndex = 0;return matchCore(str, strIndex, pattern, patternIndex);
}public boolean matchCore(char[] str, int strIndex, char[] pattern, int patternIndex) {//str到尾,pattern到尾,匹配成功if (strIndex == str.length && patternIndex == pattern.length) {return true;}//str未到尾,pattern到尾,匹配失败if (strIndex != str.length && patternIndex == pattern.length) {return false;}//str到尾,pattern未到尾(不一定匹配失败,因为a*可以匹配0个字符)if (strIndex == str.length && patternIndex != pattern.length) {//只有pattern剩下的部分类似a*b*c*的形式,才匹配成功if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {return matchCore(str, strIndex, pattern, patternIndex + 2);}return false;}//str未到尾,pattern未到尾if (patternIndex + 1 < pattern.length && pattern[patternIndex + 1] == '*') {if (pattern[patternIndex] == str[strIndex] || (pattern[patternIndex] == '.' && strIndex != str.length)) {//三种可能://1、模式串当前字符出现0次,即*表示当前字符出现0次,则str=str,pattern=pattern+2;//2、模式串当前字符出现1次,即*表示当前字符出现1次,则str=str+1,pattern=pattern+2;//3、模式串当前字符出现2次或2次以上,即*表示当前字符出现2次或以上,则str=str+1,pattern=pattern;return matchCore(str, strIndex, pattern, patternIndex + 2)//*匹配0个,跳过|| matchCore(str, strIndex + 1, pattern, patternIndex + 2)//*匹配1个,跳过|| matchCore(str, strIndex + 1, pattern, patternIndex);//*匹配1个,再匹配str中的下一个} else {//直接跳过*(*匹配到0个)//如果当前字符不匹配,则只能让*表示当前字符出现0次,则str=str,pattern=pattern+2;return matchCore(str, strIndex, pattern, patternIndex + 2);}}//模式串下一字符不为*if (pattern[patternIndex] == str[strIndex] || (pattern[patternIndex] == '.' && strIndex != str.length)) {return matchCore(str, strIndex + 1, pattern, patternIndex + 1);}return false;}
}
复制代码

54、表示数值的字符串

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

思路1:正则表达式

public class Solution {public boolean isNumeric(char[] str) {String string = String.valueOf(str);return string.matches("[\\+-]?[0-9]*(\\.[0-9]*)?([eE][\\+-]?[0-9]+)?");}
}
复制代码

思路2:

public class Solution {boolean isNumeric(char[] s) {if (s.length == 0)return false;if ((s.length == 1) && (s[0] < '0' || s[0] > '9'))return false;if (s[0] == '+' || s[0] == '-') {if (s.length == 2 && (s[1] == '.'))return false;} else if ((s[0] < '0' || s[0] > '9') && s[0] != '.')return false;// 首位既不是符号也不是数字还不是小数点,当然是falseint i = 1;while ((i < s.length) && (s[i] >= '0' && s[i] <= '9'))i++;if (i < s.length && s[i] == '.') {i++;// if(i>=s.length) return false;while ((i < s.length) && (s[i] >= '0' && s[i] <= '9'))i++;}if (i < s.length && (s[i] == 'e' || s[i] == 'E')) {i++;if ((i < s.length) && (s[i] == '+' || s[i] == '-')) {i++;if (i < s.length)while ((i < s.length) && (s[i] >= '0' && s[i] <= '9'))i++;elsereturn false;} else if (i < s.length) {while ((i < s.length) && (s[i] >= '0' && s[i] <= '9'))i++;} elsereturn false;}if (i < s.length)return false;return true;}
}
复制代码

55、字符流中第一个不重复的字符

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

import java.util.*;
public class Solution {HashMap<Character, Integer> map=new HashMap();ArrayList<Character> list=new ArrayList<Character>();//Insert one char from stringstreampublic void Insert(char ch){if(map.containsKey(ch)){map.put(ch,map.get(ch)+1);}else{map.put(ch,1);}list.add(ch);}//return the first appearence once char in current stringstreampublic char FirstAppearingOnce(){   char c='#';for(char key : list){if(map.get(key)==1){c=key;break;}}return c;}
}
复制代码

56、链表中环的入口结点

题目描述 一个链表中包含环,请找出该链表的环的入口结点。

/*public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}*/
public class Solution {public ListNode EntryNodeOfLoop(ListNode pHead) {if (pHead == null || pHead.next == null)return null;// 先判断是否有环ListNode n1 = pHead;// 走一步ListNode n2 = pHead;// 走两步ListNode n = null;// 记录n1,n2碰面的点while (n2 != null && n2.next != null) {n2 = n2.next.next;n1 = n1.next;if (n2 == n1) {n = n2;// 记录碰头节点break;}}// 求出环中节点数量int num = 0;ListNode temp = n;// n的镜像do {temp = temp.next;num++;} while (temp != n);ListNode node1 = pHead;ListNode node2 = pHead;// node1先走num步,然后node1,node2同时走,碰头的地方即入口节点for (int i = 0; i < num; i++) {node1 = node1.next;}int num1 = 0;while (node1 != node2) {node1 = node1.next;node2 = node2.next;num1++;}return node1;}
}
复制代码

57、删除链表中重复的结点

题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

思路:重点是第一个也可能是重复的点,因此新建一个preNode节点保存前一个节点

/**public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}
*/
public class Solution {public ListNode deleteDuplication(ListNode pHead){if(pHead==null)return null;ListNode preNode = null;ListNode node = pHead;while(node!=null){ListNode nextNode = node.next;boolean needDelete = false;//判断相邻两个点是否相等if(nextNode!=null&&nextNode.val==node.val){needDelete = true;}if(!needDelete){preNode = node;node = node.next;}else{int value = node.val;ListNode toBeDel = node;while(toBeDel!=null&&toBeDel.val == value){nextNode = toBeDel.next;toBeDel = nextNode;//此处不能少,找到第一个pHead,以后的preNode就不为null了if(preNode==null)pHead = nextNode;elsepreNode.next = nextNode;node = nextNode;}}}return pHead;}
}复制代码

58、二叉树的下一个结点

题目描述 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

思路:画图分析,考虑三种情况 [图片上传失败...(image-af1795-1558756468476)]

/**
public class TreeLinkNode {int val;TreeLinkNode left = null;TreeLinkNode right = null;TreeLinkNode parent= null;TreeLinkNode(int val) {this.val = val;}
}
*/
public class Solution {TreeLinkNode GetNext(TreeLinkNode node){if(node==null) return null;if(node.right!=null){    //如果有右子树,则找右子树的最左节点node = node.right;while(node.left!=null) node = node.left;return node;}while(node.parent!=null){ //没右子树,则找第一个当前节点是父节点左孩子的节点if(node.parent.left==node) return node.parent;node = node.parent;}return null;   //退到了根节点仍没找到,则返回null}
}
复制代码

59、对称的二叉树

题目描述 请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。

/**
public class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;}}
*/
public class Solution {boolean isSymmetrical(TreeNode pRoot) {    return isSymmetrical(pRoot,pRoot);}//定义两个遍历,一个前序遍历,一个是和前序遍历相反的,先右后左的遍历boolean isSymmetrical(TreeNode pRoot1, TreeNode pRoot2) {if (pRoot1 == null && pRoot2 == null)return true;if (pRoot1 == null || pRoot2 == null)return false;if (pRoot1.val != pRoot2.val)return false;return isSymmetrical(pRoot1.left,pRoot2.right) && isSymmetrical(pRoot1.right, pRoot2.left);}
}
复制代码

60、把二叉树打印成多行

题目描述 从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。

import java.util.*;/**
public class TreeNode {int val = 0;TreeNode left = null;TreeNode right = null;public TreeNode(int val) {this.val = val;}}
*/
public class Solution {ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();if(pRoot == null){return result;}//使用队列,先进先出Queue<TreeNode> layer = new LinkedList<TreeNode>();ArrayList<Integer> layerList = new ArrayList<Integer>();layer.add(pRoot);int start = 0, end = 1;//start记录本层打印了多少个,end记录下一层要打印多少个while(!layer.isEmpty()){TreeNode cur = layer.remove();layerList.add(cur.val);//添加本行打印的List里start++;//每打印一个节点,就把此节点的下一层的左右节点加入队列,并记录下一层要打印的个数if(cur.left!=null){layer.add(cur.left);           }if(cur.right!=null){layer.add(cur.right);}//本层打印完毕if(start == end){end = layer.size();start = 0;result.add(layerList);layerList = new ArrayList<Integer>();}}return result;}
}
复制代码

声明:此文章为本人原创,如有转载,请注明出处

如果您觉得有用,欢迎关注我的公众号,我会不定期发布自己的学习笔记、AI资料、以及感悟,欢迎留言,与大家一起探索AI之路。

转载于:https://juejin.im/post/5ce8c1f7f265da1bad56e0b0

剑指Offer(java答案)(51-60)相关推荐

  1. 剑指Offer——Java答案

    第二章 面试需要的基础知识 数组 - 二维数组中查找 题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数, ...

  2. 剑指offer——面试题51:数组中重复的数字

    剑指offer--面试题51:数组中重复的数字 Solution1: 20180910更新.利用数组做一次hash映射,时间复杂度为O(n)O(n)O(n),空间复杂度O(n)O(n)O(n). cl ...

  3. 剑指offer java版 test3—从尾到头打印链表

    标题:剑指offer java版 test3-从尾到头打印链表 题目:输入一个链表,按链表从尾到头的顺序返回一个ArrayList. 解答:知识不够全面,用ArrayList做的 但是看到大佬们还可以 ...

  4. 牛客网剑指offer——Java题解

    剑指offer JZ1 二维数组中的查找 题目描述 在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这 ...

  5. 剑指offer最新版_剑指Offer——Java版本(持续更新)

    0 前言 邻近校招,算法要命!!! 本文为研究剑指Offer过程中的笔记,整理出主要思路以及Java版本题解,以便记忆和复习. 参考整理来自<剑指Offer 第二版>. 特别注意,对每道题 ...

  6. 牛客网剑指offer java 全部题解

    经过数月的努力,终于更完了牛客网的66道剑指offer,以下的顺序和大家在牛客网的顺序是一样的(排序也花了不少时间),希望对大家找工作/提高算法能力能起到些许帮助. 每天一道剑指offer-二维数组中 ...

  7. [剑指offer][JAVA]面试题[51][数组中的逆序对][归并排序]

    [问题描述]面试题51.数组中的逆序对 (困难) 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1:输入: [7, ...

  8. [剑指offer]面试题第[60]题[JAVA][n个骰子的点数][动态规划][空间优化]

    [问题描述][中等] 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率.你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集 ...

  9. 【剑指offer】面试题60:n个骰子的点数(Java)

    把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率. 你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个 ...

  10. [剑指offer][JAVA]面试题第[31]题[栈的压入、弹出序列][栈]

    [问题描述][中等] 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4 ...

最新文章

  1. 打算把我的视频工具整合一下
  2. [04-05]box框模型(Box Model)定义了元素框处理元素内容、内边距、边框和外边距的方式...
  3. 【渝粤教育】 国家开放大学2020年春季 1108钢结构(本) 参考试题
  4. 微型计算机技术6,微型计算机技术课后习题6-8章答案.ppt
  5. 【原创】自己编写的JavaGUI一键生成(hibernate/spring/mvc/maven)工具(附带视频教程源码)...
  6. 1.4 Flink HDFS Connector /Flink HDFS连接器
  7. Servlet和Tomcat底层分析
  8. 微信小程序云开发教程-墨刀原型工具入门
  9. linux find命令按文件内容查找,linux下的find文件查找命令与grep文件内容查找命令...
  10. python秒杀神器苏宁_python实现自动登录 签到 京东 苏宁
  11. 机器学习实战——逻辑回归和线性判别分析
  12. SDN跟网络虚拟化的完美结合
  13. h5 数字变化_那些H5用到的技术(6)——数字滚动特效
  14. IcoFX v3.6.0 ICO图标制作工具中文便携版
  15. 多线程与高并发day04
  16. MAC下用F9-F12模拟PageUP/PageDown/HOME/END
  17. Three.js实现台灯的灯光效果
  18. 干货 :什么是数据科学?如何把数据变成产品?
  19. 解开“艾达之谜”:关于第一位程序员你所不知的故事
  20. 关于matlab的相关性函数

热门文章

  1. git bash here创建项目无法选择m_你应该知道的10个Git命令
  2. 怎么安装python2.7_如何在Windows 7安装Python2.7
  3. controller接收json数据_SpringBoot实战(二):SpringMvc接收xml请求
  4. 微软的python开发工具_面向 Python 开发人员的 Azure 工具
  5. 子之错父之过什么意思_胎教是什么意思?胎教有何意义?
  6. nGQL中vid值过长被截断的处理方法
  7. 计算机应用网站设计,《计算机应用基础》课程网站的设计与实现
  8. c语言图像浏览器,单片机采用浏览器进行监控将给软件的编程带来极大的便利...
  9. python 做网页_女生30岁以前,怎么早做打算
  10. Android自定义app图标,自定义app图标(Icon) - Cordova中文网