【面试编程题】7-剑指offer之高质量的代码

下面的题来着剑指offer第3章 高质量的代码。题目比较简单,主要考察的是代码的完整性,代码的鲁棒性。

1、数值的整数次方,数值的幂

题目描述

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

思路:
采用暴力算法,n次幂就乘以n次,时间复杂度太高;
应该采用分治的思想,但要注意负数次幂的情况。

public class Solution {
    public double Power(double base, int exponent) {

        if(exponent==0)
            return 1;
        if(exponent==1)
            return base;
        double tmp=Power(base,Math.abs(exponent)/2);

        if(exponent%2==0)
            tmp=tmp*tmp;
        else
            tmp=tmp*tmp*base;
        if(exponent<0)
            return 1/tmp;
        return tmp;
  }
}

2.调整数组顺序使奇数位于偶数前面

题目描述

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

思路:
这道题要保证交换后奇数和奇数,偶数和偶数之间的相对位置不变,只想到了遇到奇数就把前面偶数向后移,时间复杂度为n的平方,如果不保证交换后的顺序,可以使用前后两个指针的方法。

public class Solution {
    public void reOrderArray(int [] array) {
        for(int i=0;i<array.length;i++){
            if(array[i]%2!=0){
                int tmp=array[i];
                int j=i-1;
                while(j>=0 && array[j]%2==0){
                    array[j+1]=array[j];
                    j--;
                }
                array[j+1]=tmp;
            }
        }
    }
}

3.链表中倒数第k个结点
题目描述

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

思路:
使用前后指针,快、前指针比后指针多走k个点,当前指针到达链表尾部的时候,后指针就是倒数第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) {
        ListNode p1=head;
        ListNode p2=head;
        while(k>0 && p2!=null){
            p2=p2.next;
            k--;
        }
        if(k!=0)
            return null;
        while(p2!=null){
            p1=p1.next;
            p2=p2.next;
        }
        return p1;
    }
}

4.反转链表

题目描述

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

思路:
使用双指针,主要处理头节点

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode ReverseList(ListNode head) {
        if(head==null || head.next==null)
            return head;
        ListNode p1=head;
        ListNode p2=head.next;
        p1.next=null;
        ListNode tmp;
        while(p2!=null){            
            tmp=p2.next;
            p2.next=p1;
            p1=p2;
            p2=tmp;
        }
        return p1;
    }
}

5.合并两个排序的链表

题目描述

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

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode Merge(ListNode list1,ListNode list2) {
        ListNode list=new ListNode(0);
        ListNode result=list;
        while(list1!=null && list2!=null){
            if(list1.val<=list2.val){
               list.next=list1;
               list1=list1.next;            
            }else{
                list.next=list2;
                list2=list2.next;
            }
            list=list.next;
        }
        if(list1!=null)
            list.next=list1;
        if(list2!=null)
            list.next=list2;
        return result.next;
    }
}

6.树的子结构

题目描述

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

思路:
做树结构类型的题没有一次递归解决不了的,如果不行,那就两次递归

/**
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) {
        if(root2==null || root1==null)
            return false;
        if(root1.val==root2.val ){
                if( isSubtree(root1,root2))
                    return true;
        }
        return HasSubtree(root1.left,root2) ||
                    HasSubtree(root1.right,root2);


    }
    public boolean isSubtree(TreeNode root1,TreeNode root2){
        if(root2==null)
            return true;
        if(root1!=null && root2!=null && root1.val==root2.val){
            return isSubtree(root1.left,root2.left) &&
                    isSubtree(root1.right,root2.right);
        }else{
            return false;
        }                    

    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值