0
点赞
收藏
分享

微信扫一扫

剑指Offer第三章面试题(Java版)

绪风 2022-02-08 阅读 60


面试11:数值的整数次方


给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。


public class Solution {
static boolean flag_invalidinput = false;

public double Power(double base, int exponent) {
double result = 0.0;
//判断是否输入有效
if(equals(base, 0.0)&&exponent<0){
flag_invalidinput = true;
return 0.0;
}

int absexponent = exponent;
//判断指数是正数还是负数
if(exponent<0)
absexponent = -exponent;

result = powerUnsignedNum(base, absexponent);
//如果是负数求倒数。
if (exponent<0) {
result = 1.0/result;
}

return result;
}


public double powerUnsignedNum(double base, int absexponent){

double result = 0.0;
if(absexponent==0)
return 1;
if(absexponent==1)
return base;
result = powerUnsignedNum(base, absexponent>>1);
result = result*result;

if((absexponent&0x1)==1){
result *= base;
}
return result;
}


public boolean equals(double num1,double num2){
return (num1-num2<0.0000001)&&(num1-num2>-0.0000001)?true:false;
}
}

注:

使用位运算符的效率比乘除法及求余运算效率高很多。

面试题12:打印1到最大的n位数

public void  printToMaxOfNDigits(int n) {
//小于等于0,直接退出
if(n<=0){
return;
}

char[] chs = new char[n];
for (int i = 0; i < 10; i++) {
chs[0] = (char) (i +'0');
printToMaxOfNDigits(chs,n,0);
}
}


public void printToMaxOfNDigits(char[] chs,int length,int index){

if(index == length-1){
printNumber(chs);
return;
}

for (int i = 0; i < 10; i++) {
chs[index+1] = (char) (i+'0');//chs[1]='0'
printToMaxOfNDigits(chs,length,index+1);
}
}

//打印数字
public void printNumber(char[] number){
boolean isBegin = true;//假设开始为0
for (int i = 0; i < number.length; i++) {
if (isBegin&&number[i]!='0') {
isBegin = false;//设置开始不为0
}

if(!isBegin){
System.out.print(number[i]);
}
}
System.out.print("-");
}

面试题13:在O(1)的时间删除链表结点

public class Demo13 {
//需要确保删除的元素在链表中
public void DeleteNode(Node head,Node deleteNode){

//要删除的节点不为空
if(deleteNode.next!=null){
Node tempNode = deleteNode.next;
deleteNode.value = tempNode.value;
deleteNode.next = tempNode.next;

tempNode.next = null;

}else if(head==deleteNode){//这里有个隐含条件了,deleteNode.next=null
head.next=null;//链表只有一个节点,删除头结点(也是尾节点)

}else {//链表有多个节点,删除的尾节点
Node temp = head;
while(temp.next!=deleteNode){
temp = temp.next;
}
temp.next = null;
deleteNode = null;
}
}
class Node{
Node next;
int value;
}
}

注:本来删除一个链表节点我们需要知道该节点的头一个节点这就需要O(n)的时间,题目要求我们要在O(1)的时间内完成。因此我们只能找到该节点的下一个节点,将值覆盖该节点,然后删除下一个节点。这题存在一个缺陷就是我们必须要确保该节点存在于该链表中。

面试题14:调整数组顺序使奇数位于偶数前面

public class Solution {
public static void reOrderArray(int [] array) {
int low=0;
int high = array.length-1;

while(high>low){
//如果是偶数,继续循环
/*while((high>low)&&(array[high]&0x1)==0){
high--;
}*/
while((high>low)&&isOdd(array[high])){
high--;
}

//如果是奇数,继续循环
/*while((high>low)&&(array[low]&0x1)==1){//加上判断条件high>low,可以节约一定步骤
low++;
}*/
while((high>low)&&!isOdd(array[low])){
low++;
}

if(high>low){
int temp = array[low];
array[low] = array[high];
array[high] = temp;
}
}

}

public static boolean isOdd(int num){
return (num&0x1)==0?true:false;
}

public static boolean isPlus(int num){
return num>=0?true:false;
}
}

附加:


输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。


public class Solution {
public void reOrderArray(int [] array) {
int len = array.length;

for (int i = 0; i < len; i++) {
if((array[i]&0x1)==0){//判断是否是偶数
int j=i;
int temp = array[j];
while(j<array.length-1){
array[j] = array[j+1];
j++;
}
array[j]=temp;
len--;//表名后面已经有一个偶数了

//i=-1;//交换之后,控制i每次从第一个开始比较
i--;//相对于i=-1更优
}
}
}
}

面试题15:链表中倒数第k个结点


输入一个链表,输出该链表中倒数第k个结点。


/*
public class ListNode {
int val;
ListNode next = null;

ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
if (head==null||k==0) {
return null;
}

ListNode firstNode = head;
ListNode secordNode = head;
for (int i = 0; i < k-1; i++) {
if(secordNode.next!=null){
secordNode = secordNode.next;
}else {
return null;
}

}

while(secordNode.next!=null){
firstNode = firstNode.next;
secordNode = secordNode.next;
}

return firstNode;
}
}

面试题16:反转链表


输入一个链表,反转链表后,输出链表的所有元素。


非递归版

/*
public class ListNode {
int val;
ListNode next = null;

ListNode(int val) {
this.val = val;
}
}*/
public class Solution
{
public ListNode ReverseList(ListNode head) {
ListNode newHead=null;
ListNode first=null;
ListNode second=head;
ListNode three=null;

if(second==null){
return second;
}

while(second!=null){
three = second.next;
if(three==null)
newHead = second;

second.next = first;

first = second;
second = three;

}
return newHead;
}
}

递归版

剑指Offer第三章面试题(Java版)_数组

public class Demo16 {
public class ListNode {
int val;
ListNode next = null;

ListNode(int val) {
this.val = val;
}
}

public ListNode reverse(ListNode head) {
if (null == head || null == head.next) {
return head;
}
ListNode reversedHead = reverse(head.next);

head.next.next = head;
head.next = null;
return reversedHead;
}
/**
* 测试
*/
public static void main(String[] args) {
Demo16 demo16 = new Demo16();
ListNode node1 = demo16.new ListNode(1);
ListNode node2 = demo16.new ListNode(2);
ListNode node3 = demo16.new ListNode(3);
ListNode node4 = demo16.new ListNode(4);
ListNode node5 = demo16.new ListNode(5);
node1.next = node2;
node2.next = node3;
node3.next = node4;
node4.next = node5;

ListNode reListNode = demo16.reverse(node1);

ListNode tempListNode = reListNode;
while (tempListNode!=null) {
System.out.println(tempListNode.val);
tempListNode = tempListNode.next;
}

}
}

面试题17:合并两个排序的链表


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


/*
public class ListNode {
int val;
ListNode next = null;

ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
//解决鲁棒性问题
if(list1 == null)
return list2;
if(list2 == null)
return list1;

ListNode mergeList = null;
if(list1.val>list2.val){
mergeList = list2;
mergeList.next = Merge(list1, list2.next);
}else {
mergeList = list1;
mergeList.next = Merge(list1.next, list2);
}

return mergeList;
}
}

面试题18:树的子结构


输入两颗二叉树A,B,判断B是不是A的子结构。


/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;

public TreeNode(int val) {
this.val = val;

}

}
*/
public class Solution {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
boolean result = false;

if(root1 != null && root2 !=null){
if(root1.val == root2.val){
result = DoesTree1HavaTree2(root1, root2);
}

//遍历左子树
if(!result){
result = HasSubtree(root1.left,root2);
}

//遍历右子树
if(!result){
result = HasSubtree(root1.right,root2);
}
}
return result;
}

public boolean DoesTree1HavaTree2(TreeNode root1,TreeNode root2){
//为什么要判断是否为null? 因为该函数还会进行递归。
if (root2==null) {
return true;
}
if(root1==null){
return false;
}
if (root1.val != root2.val) {
return false;
}
return DoesTree1HavaTree2(root1.left,root2.left)
&&DoesTree1HavaTree2(root1.right,root2.right);
}
}



举报

相关推荐

0 条评论