剑指offer36-40
Posted lgh544
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer36-40相关的知识,希望对你有一定的参考价值。
36 两个链表的第一个公共节点
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的)
时间复杂度:O(m+n), m,n分别为链表A,B的长度,最坏情况下,公共结点为最后一个,需要遍历m+n个结点
空间复杂度:O(1)
看下面的链表例子:
0-1-2-3-4-5-null
a-b-4-5-null
代码的ifelse语句,对于某个指针p1来说,其实就是让它跑了连接好的的链表,长度就变成一样了。
如果有公共结点,那么指针一起走到末尾的部分,也就一定会重叠。看看下面指针的路径吧。
p1: 0-1-2-3-4-5-null(此时遇到ifelse)-a-b-4-5-null
p2: a-b-4-5-null(此时遇到ifelse)0-1-2-3-4-5-null
因此,两个指针所要遍历的链表就长度一样了!
如果两个链表存在公共结点,那么p1就是该结点,如果不存在那么p1将会是null。
public class FindFirstCommonNode_36 {
public static void main(String[] args) {
FindFirstCommonNode_36 result = new FindFirstCommonNode_36();
ListNode7 root = new ListNode7(4);
ListNode7 node1 = new ListNode7(1);
ListNode7 node2 = new ListNode7(3);
ListNode7 node3 = new ListNode7(4);
ListNode7 node4 = new ListNode7(5);
ListNode7 root2 = new ListNode7(6);
ListNode7 node6 = new ListNode7(7);
ListNode7 node7 = new ListNode7(8);
root.next = node1;
node1.next = node2;
node2.next = node3;
node3.next = node4;
root2.next = node6;
node6.next = node7;
node7.next = node2;
ListNode7 res = result.FindFirstCommonNode(root,root2);
if(res != null)
System.out.println(res.val);
}
public ListNode7 FindFirstCommonNode(ListNode7 listNode,ListNode7 listNode2) {
if(listNode == null || listNode2 == null) return null;
ListNode7 p1 = listNode;
ListNode7 p2 = listNode2;
while(p1 != p2) {
p1 = p1.next;
p2 = p2.next;
if(p1 != p2) {
if(p1 == null)p1 = listNode2;
if(p2 == null)p2 = listNode;
}
}
return p1;
}
}
class ListNode7{
int val;
ListNode7 next;
public ListNode7(int val) {
this.val = val;
}
}
37数字在排序数组中出现的次数
统计一个数字在排序数组中出现的次数
时间复杂度:O(logN)
空间复杂度:O(1)
就是先二叉搜索找一下这个元素的位置,然后再开始遍历搜索一下。
没有写main函数
import java.util.Arrays;
public class Solution {
public int GetNumberOfK(int [] array , int k) {
int index = Arrays.binarySearch(array, k);
if(index<0)return 0;
int cnt = 1;
for(int i=index+1; i < array.length && array[i]==k;i++)
cnt++;
for(int i=index-1; i >= 0 && array[i]==k;i--)
cnt++;
return cnt;
}
}
38 二叉树的深度
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。(未写Main函数)
//递归
public int TreeDepth(TreeNode root) {
if(root==null){
return 0;
}
int left=TreeDepth(root.left);
int right=TreeDepth(root.right);
return Math.max(left,right)+1;
}
//非递归:利用队列,count是当前的节点,nextcount是当前深度总的节点。【总是要遍历到当前深度的最后一个节点,深度才加1】
import java.util.LinkedList;
import java.util.Queue;
public int TreeDepth1(TreeNode root) {
if(root==null) {
return 0;
}
Queue<TreeNode> q=new LinkedList<TreeNode>();
q.add(root);
int d=0,count=0,nextcount=q.size();
while(q.size()!=0) {
TreeNode t=q.poll();
count++;
if(t.left!=null) {
q.add(t.left);
}
if(t.right!=null) {
q.add(t.right);
}
if(count==nextcount) {
d++;
count=0;
nextcount=q.size();
}
}
return d;
}
39 平衡二叉树(未写main函数)
空间复杂度:O(N)
public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
return depth(root) != -1;
}
public int depth(TreeNode root){
if(root == null)return 0;
int left = depth(root.left);
if(left == -1)return -1; //如果发现子树不平衡之后就没有必要进行下面的高度的求解了
int right = depth(root.right);
if(right == -1)return -1;//如果发现子树不平衡之后就没有必要进行下面的高度的求解了
if(left - right <(-1) || left - right > 1)
return -1;
else
return 1+(left > right?left:right);
}
}
40 数组中只出现一次的数字
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
时间复杂度:O(n)
空间复杂度:O(n)
import java.util.HashMap;
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
//哈希算法
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for(int i=0; i < array.length; i++){
if(map.containsKey(array[i]))
map.put(array[i],2);
else
map.put(array[i],1);
}
int count = 0;
for(int i=0; i < array.length; i++){
if(map.get(array[i]) == 1){
if(count == 0){
num1[0] = array[i];
count++;
}else
num2[0] = array[i];
}
}
}
}
以上是关于剑指offer36-40的主要内容,如果未能解决你的问题,请参考以下文章
LeetCode810. 黑板异或游戏/455. 分发饼干/剑指Offer 53 - I. 在排序数组中查找数字 I/53 - II. 0~n-1中缺失的数字/54. 二叉搜索树的第k大节点(代码片段
剑指 Offer(第 2 版)完整题解笔记 & C++代码实现(LeetCode版)
剑指 Offer(第 2 版)完整题解笔记 & C++代码实现(LeetCode版)