Java--剑指offer(8)

时间:2021-09-08 22:49:32

36.输入两个链表,找出它们的第一个公共结点。

  解题思路:这里主要是把两个链表的节点都放入两个栈中,这样就可以按照出栈的方式来比较节点,因为单链表只要是有相同的节点,那么之后的节点也都是一样的,所以如果出栈的节点不相同的话就可以返回之前保存的commonNode变量,这么变量的值就是第一个共同的节点。

import java.util.Stack;
/*
public class ListNode {
int val;
ListNode next = null; ListNode(int val) {
this.val = val;
}
}*/ public class Solution {
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
if(pHead1 == null || pHead2 == null)
return null; ListNode commonNode = null;
Stack<ListNode> s1 = new Stack<ListNode>();
Stack<ListNode> s2 = new Stack<ListNode>(); s1.push(pHead1);
s2.push(pHead2); ListNode p1 = pHead1;
ListNode p2 = pHead2;
while(p1.next != null){
s1.push(p1.next);
p1 = p1.next;
}
while(p2.next != null){
s2.push(p2.next);
p2 = p2.next;
}
while(s1.peek() == s2.peek()){
commonNode = s1.peek();
if(s1.peek() != null)
s1.pop();
if(s2.peek() != null)
s2.pop();
//如果s1或者s2为空就直接跳出循环
if(s1.empty() || s2.empty())
break;
} return commonNode;
}
}

37.统计一个数字在排序数组中出现的次数。

public class Solution {
public int GetNumberOfK(int [] array , int k) {
int len = array.length;
int first = -1;
int last = -1;
int num = 0; for(int i = 0; i < len; i++){
if(array[i] == k){
first = i;
break;
}
}
for(int i = len-1; i >= 0; i--){
if(array[i] == k){
last = i;
break;
}
} //如果first和last为-1的话,证明数组中没有和k相同的
if(first != -1 && last != -1){
num = last - first +1;
} else{
num = 0;
} return num;
}
}

38.输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。

/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
};*/
public class Solution {
public int TreeDepth(TreeNode pRoot)
{
if(pRoot == null)
return 0; int nLeft = TreeDepth(pRoot.left);
int nRight = TreeDepth(pRoot.right); return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
}
}

39.输入一棵二叉树,判断该二叉树是否是平衡二叉树。

  这一种方法使用了递归的方式,虽然十分简洁,但是节点会被重复遍历多次,所以时间效率不高。

public class Solution {
public boolean IsBalanced_Solution(TreeNode root) {
//空二叉树也是平衡二叉树
if(root == null)
return true; int left = TreeDepth(root.left);
int right = TreeDepth(root.right); int diff = left - right;
if(diff > 1 || diff < -1)
return false; return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);
} public int TreeDepth(TreeNode pRoot)
{
if(pRoot == null)
return 0; int nLeft = TreeDepth(pRoot.left);
int nRight = TreeDepth(pRoot.right); return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
}
}

40.一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
int length = array.length;
if(array==null ||length<2)
return ;
int resultExclusiveOR = 0;
for(int i=0;i<length;i++)
resultExclusiveOR ^= array[i]; int indexOf1 = findFirstBitIs1(resultExclusiveOR);
for(int i=0;i<length;i++){
if(isBit1(array[i], indexOf1))
num1[0]^=array[i];
else
num2[0]^=array[i];
}
}
public int findFirstBitIs1(int num){
int indexBit = 0;
while(((num & 1)==0) && (indexBit)<8*4){
num = num >> 1;
++indexBit;
}
return indexBit;
}
public boolean isBit1(int num,int indexBit){
num = num >> indexBit;
return (num & 1) == 1;
}
}