《剑指offer》Java实现(11-20)

《剑指offer》Java实现(11-20)

11.给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0

public class Solution {
    public double Power(double base, int exponent) {
        double result=0;
        /**
		 * base为0.0时
		 */
        if(equal(base,0.0)){
            return 0.0;
        }
        if(equal(base,1.0)||equal(exponent,0.0)){
            return 1.0;
        }
        if(exponent>0){
            result=multiply(base,exponent);
        }else{
            result=multiply(1/base,-exponent);
        }
        return result;
    }
    
    //定义指数函数 x^n  
    private static double multiply(double x,double n){
        double sum=1;
        for(int i=0;i<n;i++){
            sum*=x;
        }
        return sum;
    }
    //定义相等函数equal()
    private static boolean equal(double a,double b){
        if(a-b<0.000001&&a-b>-0.000001){
            return true;
        }
        return false;
    }
}

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

public class Solution {
    public void reOrderArray(int [] array) {
        if(array==null||array.length==0){
          return;
      }
      //计算奇数的个数
        int oddNum=0;
        for(int i=0;i<array.length;i++)
        {
            if(array[i]%2==1)
            {
                oddNum++;
            }
        }
        //复制一个数组,如果要直接在原来的数组上操作没有办法赋值,很混乱,无法实现
        int [] copy=array.clone();
        //将数组分为两个部分,一部分存储奇数,一部分存储偶数
        //奇数从oddflag开始存储
        //偶数从evenflag开始存储
        int oddflag=0;
        int evenflag=oddNum;
        for(int j=0;j<copy.length;j++)
        {
            if(copy[j]%2==1)
            {
                array[oddflag]=copy[j];
                oddflag++;
            }else
            {
                array[evenflag]=copy[j];
                evenflag++;
            }
        }
    }
}

13.输入一个链表,输出该链表中倒数第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 fast=head;
        ListNode slow=head;
        while(k-->1){
            if(fast.next!=null){
                fast=fast.next;
            }else{
                return null;
            }
        }
        while(fast.next!=null){
            fast=fast.next;
            slow=slow.next;
        }
        return slow;
    }
}

还有一个思路:就是把链表的所有元素压入栈中,然后出栈。这时,栈中出栈的元素顺序正好是链表中倒数第几个元素。但是时间复杂度较大,不建议。
14.输入一个链表,反转链表后,输出新链表的表头。

/*
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){
            return null;
        }
        ListNode t=null;
        //一直交换元素,直到t和最后一个元素交换,此时即为反转链表的头
        while(head!=null){
            //定义p来缓存
            ListNode p=head.next;
            head.next=t;
            t=head;
            head=p;
        }
        return t;
    }
}

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

/*
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 newHead=null;
        //递归   保证有序
        if(list1.val<=list2.val){
            newHead=list1;
            newHead.next=Merge(list1.next,list2);
        }else{
            newHead=list2;
            newHead.next=Merge(list1,list2.next);
        }
        return newHead;
    }
}

16.输入两棵二叉树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) {
        //递归  比较他们的子树是否相等
        //如果根节点相等,继续递归比较他们的左子树的右子树
       boolean result = false;
        //如果为空
       if (root1 == null||root2 == null){
           return false;
       } 
       //如果不为空 继续判断
        if(root1 != null && root2 != null){
        //该二叉树不是左小右大的
        if(root1.val==root2.val){
            result=isEqual(root1,root2);
        }
        if(!result){
            result=isEqual(root1.left,root2);
        }
        if(!result){
            result=isEqual(root1.right,root2);
        } 
      }
      return result;
    }
    
    
public boolean isEqual(TreeNode root1,TreeNode root2){
     //子树已经判断完毕了则结束,表明整个过程都为true,最终返回true
     if(root2 == null){
         return true;
     } 
    //子树还没空,父树先走到空了,那么肯定是不是子树结构的
     if(root1 == null) {
         return false;
     }
    //值不相等
      if(root1.val != root2.val){
          return false;
      }
     return isEqual(root1.left,root2.left)&& isEqual(root1.right,root2.right);
   }
}

17.操作给定的二叉树,将其变换为源二叉树的镜像。
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 {
public void Mirror(TreeNode root) {
while(root==null){
return;
}

    Stack<TreeNode> stack=new Stack<>();
    while(root!=null||!stack.isEmpty()){
        while(root!=null){
            //交换位置
            TreeNode temp=root.left;
            root.left=root.right;
            root.right=temp;
            stack.push(root);//压栈
            root=root.left;//下一次递归
        }
        if(!stack.isEmpty()){
            root=stack.pop();
            root=root.right;
        }
    }
}

}
18.输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

private static void printMatrixInCircle(int[][] numbers,int rows,int colums,int start){
		int endX = colums-1-start;
		int endY = rows-1-start;
		
		/**从左向右打印一行*/
		for(int i=start;i<=endX;i++){
			int number=numbers[start][i];
			System.out.print(number+" ");
		}
		/**从上到下打印一列*/
		if(start<endY){
			for(int i=start+1;i<=endY;i++){
				int number = numbers[i][endX];
				System.out.print(number+" ");
			}
		}
		/**从右向左打印一行*/
		if(start<endX && start<endY){
			for(int i=endX-1;i>=start;i--){
				int number = numbers[endY][i];
				System.out.print(number+" ");
			}
		}
		/**从下到上打印一列*/
		if(start<endX && start<endY-1){
			for(int i=endY-1;i>=start;i--){
				int number = numbers[i][start];
				System.out.print(number+" ");
			}
		}
	}
	public static void printMatrixClockwisely(int[][] numbers,int rows,int colums){
		if(numbers==null || colums<0 || rows<0)
			return;
		int start=0;
		while(colums>start*2 && rows>start*2){
			printMatrixInCircle(numbers,rows,colums,start);
			++start;
		}
		System.out.println();
	}

19.定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。
注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。

import java.util.Stack;
//定义两个栈,一个存放入的值,另一个存最小值
//peek()函数返回栈顶的元素,但不弹出该栈顶元素。
//pop()函数返回栈顶的元素,并且将该栈顶元素出栈。
public class Solution {
    Stack<Integer> stack1=new Stack<>();
    Stack<Integer> stack2=new Stack<>();
    public void push(int node) {
        stack1.push(node);
        if(stack2.isEmpty()){
            stack2.push(node);
        }else{
            if(stack2.peek()>node){
                stack2.push(node);
            }
        }
    }
    
    public void pop() {
        if(stack1.pop()==stack2.peek()){
            stack2.pop();
        }
    }
    //返回栈顶元素
    public int top() {
        return stack2.peek();
    }
    
    public int min() {
        return stack2.peek();
    }
}

20.输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

import java.util.ArrayList;
import java.util.*;
public class Solution {
    public boolean IsPopOrder(int [] pushA,int [] popA) {
        //为空的情况
        if(pushA==null||popA==null){
            return false;
        }
        Stack<Integer> stackData=new Stack<>();
        //j代表pushA数组下标,i代表popA数组下标
        int j=0,i=0;
        stackData.push(pushA[j]);
        while(j<pushA.length){
            //popA中元素全部比较完成,说明此数组序列是pushA
            if(i==popA.length){
                return true;
            }
            //仅仅判断stackData为empty,不能说明此数组序列是pushA所对应的删除序列
            if(i!=popA.length && stackData.isEmpty()||stackData.peek()!=popA[i]){
                ++j;
                if(j<pushA.length)
                    stackData.push(pushA[j]);
            }else if(stackData.peek()==popA[i]){
                i++;
                stackData.pop();
            }
        }
        return false;
    }
}

本人才疏学浅,如有错误,烦请指出,谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值