第一题:
/**
* 在一个二维数组中,
* 每一行都按照从左到右递增的顺序排序
* 每一列都按照从上到下递增的顺序排序。
* 请完成一个函数
* 输入这样的一个二维数组和一个整数
* 判断数组中是否含有该整数
*
*/
public class Demo01 {
public static void main(String[] args) {
//int std[][] = {{1,2,8,9},{2,4,9,12},{4,7,10,13,},{6,8,11,15}};
int std[][] ={{}};
System.out.println(new Demo01().Find(7, std));
}
public boolean Find(int target, int [][] array) {
boolean found = false;
int lie = array[0].length;
int hang = array.length;
int column = lie -1;
int row =0;
while(row<hang &&column>=0){
int value = array[row][column];
if(target>value){
row++;
}else if(value>target){
column--;
}else{
found = true;
break;
}
}
return found;
}
第二题:
/**
* 请实现一个函数,
* 将一个字符串中的空格替换成“%20”。
* 例如,当字符串为We Are Happy.
* 则经过替换之后的字符串为We%20Are%20Happy
* @author 大护法
*
*/
public class Demo02 {
public static void main(String[] args) {
StringBuffer str = new StringBuffer("We Are Happy");
new Demo02().replaceSpace(str);
System.out.println(new Demo02().replaceSpace(str));
}
public String replaceSpace(StringBuffer str) {
if(str == null){
return null;
}
StringBuffer newStr = new StringBuffer();
for(int i=0; i<str.length(); i++){
if(str.charAt(i) == ' '){
newStr.append('%');
newStr.append('2');
newStr.append('0');
}else{
newStr.append(str.charAt(i));
}
}
return newStr.toString();
}
}
第三题
/**
* 输入一个链表,从尾到头打印链表每个节点的值。
*
* public class ListNode {
* int val;
* ListNode next = null;
*
* ListNode(int val) {
* this.val = val;
* }
* }
*
* 思路 :可以将链表中的元素放入一个栈中
* 然后在根据栈先进先出的特点将其压入一个 list的集合中
*/
public class Demo03 {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<Integer>();
while(listNode!=null){
stack.push(listNode.val);
listNode = listNode.next;
}
ArrayList<Integer> list = new ArrayList<Integer>();
//stack.isEmpty() 判断栈是否初始化
while(!stack.isEmpty()){
list.add(stack.pop());
}
return list;
}
public static void main(String[] args) {
Stack<Integer> stack = new Stack<Integer>();
stack.push(2);
stack.push(3);
System.out.println(stack.isEmpty());
}
}
第四题
/**
* 输入某二叉树的前序遍历和中序遍历的结果,
* 请重建出该二叉树。
* 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
* 例如输入前序遍历序列
* {1,2,4,7,3,5,6,8}
* 和中序遍历序列{4,7,2,1,5,3,8,6},
* 则重建二叉树并返回。
*
*
* 注 :
* Arrays.copyOfRange(T[ ] original,int from,int to)将一个原始的数组original,
* 从小标from开始复制,复制到小标to,生成一个新的数组。
* 注意这里包括下标from,不包括下标to。
*
*
* 思路: 根据前序遍历确定二叉树的根结点 然后根据根节点递归,每次都将二叉树分成左右两边
*
* @author 大护法
*
*
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Demo04 {
public static void main(String[] args) {
int[] pre = {1,2,4,7,3,5,6,8};
int[] in = {4,7,2,1,5,3,8,6};
System.out.println(new Demo04().reConstructBinaryTree(pre, in));
}
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length == 0 || in.length==0){
return null;
}
//创建树输入根节点
TreeNode node = new TreeNode(pre[0]);
for(int i = 0; i < in.length; i++){
if(pre[0] == in[i]){
node.left = reConstructBinaryTree(Arrays.copyOfRange(pre, 1, i+1), Arrays.copyOfRange(in, 0, i));
node.right = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1,in.length));
}
}
return node;
}
}
第五题
/**
* 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
*
* 思路 : 定义了两个栈
* 可以利用栈的定义根据出栈和进栈来实现队列的基本操作
*
* @author 大护法
*
*/
public class Demo05 {
Stack<Integer> stack1 = new Stack<Integer>();
Stack<Integer> stack2 = new Stack<Integer>();
public void push(int node) {
stack1.push(node);
}
public int pop() {
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
int temp = stack2.pop();
while(!stack2.isEmpty()){
stack1.push(stack2.pop());
}
return temp;
}
}
第六题
/**
* 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
* 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。
* 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。
* NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。
* @author 大护法
*
*
*
* 注:采用2分法进行查找
*/
public class Demo06 {
public int minNumberInRotateArray(int [] array) {
if(array == null || array.length == 0) return 0;
int start = 0; //头元素
int end = array.length - 1; //尾元素
int mid = (start + end) / 2; //中间元素
//只有一个元素
if(array[end] == array[start] || array[mid] == array[end] || array[mid] == array[start]){
return findMin(array);
}
//
if(array[mid] > array[start] && array[mid] < array[end]){
return array[0];
}
while(true){
mid = (start + end) / 2;
if(array[mid] > array[start]){
start = mid;
}else if(array[mid] < array[end]){
end = mid;
}
if((start+1) == end) break;
}
return array[end];
}
public int findMin(int[] array){
int result = Integer.MAX_VALUE;
for(int i = 0; i <= array.length - 1; i++){
result = Math.min(result, array[i]);
}
return result;
}
public static void main(String[] args) {
int a[] = {6501,6828,6963,7036,7422,7674,8146,8468,8704,8717,9170,
9359,9719,9895,9896,9913,9962,154,293,334,492,1323,1479,1539,1727,
1870,1943,2383,2392,2996,3282,3812,3903,4465,4605,4665,4772,
4828,5142,5437,5448,5668,5706,5725,6300,6335};
int m = new Demo06().minNumberInRotateArray(a);
System.out.println(m);
}
}
第七题
/**
* 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项
*
* 斐波那契数列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...
* 如果设F(n)为该数列的第n项(n∈N*),那么这句话可以写成如下形式::F(n)=F(n-1)+F(n-2)
* 显然这是一个线性递推数列。
*
*
* 用迭代进行计算
* @author 大护法
*
*/
public class Demo07 {
public int Fibonacci(int n) {
if(n == 0)return 0;
if(n == 1 || n ==2){
return 1;
}
int fn1 = 1;
int fn2 = 1;
int fnsum = 0;
for(int i = 3; i<=n; i++){
fnsum = fn1 + fn2;
fn2 = fn1;
fn1 = fnsum;
}
return fnsum;
}
public static void main(String[] args) {
int m = new Demo07().Fibonacci(39);
System.out.println(m);
}
}
第八题
/**
*
* ** 递归循环
* 一只青蛙一次可以跳上1级台阶,也可以跳上2级。
* 求该青蛙跳上一个n级的台阶总共有多少种跳法。
*
* 注 :
* 台阶 方法
* f(1) 1
* f(2) 2
* f(3) 3
* f(4) 5
* f(5) 8
*
* 推出规律 f(n) = f(n-1)+f(n-2) n>2;
* @author 大护法
*
*/
public class Demo08 {
public int JumpFloor(int target) {
if(target <= 0) return 0;
if(target == 1) return 1;
if(target == 2) return 2;
int fn1 = 2;
int fn2 = 1;
int result = 0;
for(int i=3; i<=target; i++){
result = fn1+fn2;
fn2 = fn1;
fn1 = result;
}
return result;
}
}
第九题
/**
* 变态跳台阶
*
* 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。
* 求该青蛙跳上一个n级的台阶总共有多少种跳法。
*
*
* 注:
*
* f(1) = 1
* f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
* f(3) = f(3-1) + f(3-2) + f(3-3)
* ...
* f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n)
*
* 所以得出递推公式 采用递归实现
* | 1 (n=0 )
* f(n) = | 1 (n=1 )
* | 2*f(n-1) (n>=2)
*
*
* @author 大护法
*
*/
public class Demo09 {
public int JumpFloorII(int target) {
if(target <= 0){
return 0;
} else if(target == 1){
return 1;
}else{
return 2 * JumpFloorII(target - 1);
}
}
}
第十题
/**
* 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形
* 请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
*
* 注:
* 根据推到得出递推公式:
* 1 (n=1)
* f(n) 2 (n=2)
* f(n-1)+f(n-2) (n>2)
* @author 大护法
*
*/
public class Demo10 {
public int RectCover(int target) {
if(target <= 0){
return 0;
}else if(target == 1 || target == 2){
return target;
}else {
return RectCover(target-1) + RectCover(target-2);
}
}
}
第十一题(不会)
/**
* 位运算:
*
* 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
* @author 大护法
*
*/
public class Demo11 {
}
第十二题
/**
* 数值的整数次方:
*
* 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
*
* @author 大护法
*
*/
public class Demo12 {
public double Power(double base, int exponent) {
double std=1.0;
if(base == 0){
return 0.0000;
}else if(exponent<0){
exponent = Math.abs(exponent);
for(int i =0; i<exponent; i++){
std = std*base;
}
return 1/std;
}else{
for(int i=0; i<exponent; i++){
std = std*base;
}
return std;
}
}
public static void main(String[] args) {
System.out.println(new Demo12().Power(-1.25, -3));
}
}
第十三题
/**
*
*
* 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,
* 所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变
*
*
* 注:
* 定义一个新数组,然后统计新数组中的奇数和偶数的个数
* 然后对原数组进行遍历根据条件压入新的数组
* @author 大护法
*
*/
public class Demo13 {
public void reOrderArray(int [] array) {
int[] result = new int[array.length];
int numofOdd = 0; //奇数个数
for(int i =0; i<array.length; i++){
if(array[i]%2 == 1){
numofOdd ++;
}
}
int indexofOdd = 0;
int indexOfEven = numofOdd;
for(int i =0; i<array.length; i++){
if(array[i]%2 == 1){
result[indexofOdd++] = array[i];
}else{
result[indexOfEven++] = array[i];
}
}
for(int i=0;i<array.length;i++){
array[i] = result[i];
}
}
}
第十四题
/**
* 输入一个链表,输出该链表中倒数第k个结点。
*
*
*
* @author 大护法
*
*/
public class Demo14 {
public ListNode FindKthToTail(ListNode head,int k) {
if(head == null){
return head;
}
ListNode node = head;
int count = 0;
while(node != null){
count++;
node = node.next;
}
if(count<k) return null;
ListNode p = head;
for(int i =0; i<count-k; i++){
p = p.next;
}
return p;
}
}
第十五题
/**
* 输入一个链表,反转链表后,输出链表的所有元素
* @author 大护法
*
*/
public class Demo15 {
public ListNode ReverseList(ListNode head) {
if(head == null){
return null;
}
ListNode newHead = null;
ListNode pNode = head;
ListNode pPrev = null;
while(pNode != null){
pPrev = newHead;
newHead = pNode;
pNode = pNode.next;
newHead.next = pPrev;
}
return newHead;
}
}
第十六题
/**
*
* 输入两个单调递增的链表,输出两个链表合成后的链表,
* 当然我们需要合成后的链表满足单调不减规则。
* @author 大护法
*
*/
public class Demo16 {
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1==null){
return list2;
}else if(list2==null){
return list1;
}
ListNode pMergeHead = null;
if(list1.val<list2.val){
pMergeHead = list1;
pMergeHead.next = Merge(list1.next,list2);
}else{
pMergeHead = list2;
pMergeHead.next = Merge(list1,list2.next);
}
return pMergeHead;
}
}
第十七题
/**
* 输入两棵二叉树A,B,判断B是不是A的子结构。
* (ps:我们约定空树不是任意一个树的子结构)
*
* 注:
* 首先遍历 A 树 查找和B树根结点相同的节点 然后 A树以次为根节点 和 B树进行比较
*
*
* 特别注意root2 为空时候的比较
* @author 大护法
*
*/
public class Demo17 {
public boolean HasSubtree(TreeNode root1,TreeNode root2) {
if(root2 == null) return false;
if(root1 == null && root2 != null) return false;
boolean flag = false;
if(root1.val == root2.val){
flag = isSubTree(root1,root2);
}if(flag == false){
flag = HasSubtree(root1.left, root2);
if(flag == false){
flag = HasSubtree(root1.right, root2);
}
}
return flag;
}
private Boolean isSubTree(TreeNode root1,TreeNode root2) {
if(root2 == null) return true;
if(root1 == null && root2 != null) return false;
if(root1.val == root2.val){
return isSubTree(root1.left, root2.left) && isSubTree(root1.right, root2.right);
}
return false;
}
}
第十八题
/**
* 操作给定的二叉树,将其变换为源二叉树的镜像。
*
* 注:
*
* 利用递归 从根节点之后依次递归交换左右子树 便可以得到所谓镜像二叉树
* @author 大护法
*
*/
public class Demo18 {
public void Mirror(TreeNode root) {
if(root == null)
return;
if(root.left == null && root.right == null)
return;
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
if(root.left != null)
Mirror(root.left);
if(root.right != null)
Mirror(root.right);
}
}
第十九题
/**
* 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字
* 例如,如果输入如下矩阵: 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.
*
* @author 大护法
*
*/
public class Demo19 {
public ArrayList<Integer> printMatrix(int [][] matrix) {
ArrayList<Integer> list = new ArrayList<Integer>();
int rows = matrix.length; //行
int cols = matrix[0].length; //列
System.out.println("rows ="+rows+"; cols"+cols);
if(rows==0 && cols==0) return list;
int left = 0, top = 0, right = cols - 1, bottom = rows - 1;
while(rows>0 && cols>0){
for(int i=left; i<=right; i++){
list.add(matrix[top][i]);
}
for(int i=top+1; i<=bottom; i++)
{
list.add(matrix[i][right]);
}
if (top != bottom)
for(int i=right-1; i>=left; i--){
list.add(matrix[bottom][i]);
}
if (left != right)
for(int i=bottom-1; i>=top+1; i--){
list.add(matrix[i][left]);
}
left++; top++;
right--; bottom--;
rows =rows-2;
cols =cols-2;
}
return list;
}
public static void main(String[] args) {
int[][] matrix={{1},{2},{3},{4},{5}};
System.out.println(new Demo19().printMatrix(matrix));
}
}
第二十题
/**
* 定义栈的数据结构,
* 请在该类型中实现一个能够得到栈最小元素的min函数
* @author 大护法
*
*/
public class Demo20 {
Stack<Integer> stack = new Stack<Integer>();
//入栈
public void push(int node) {
stack.push(node);
}
//出栈
public void pop() {
stack.pop();
}
//返回栈顶的元素
public int top() {
return stack.peek();
}
//返回栈中最小的元素
public int min() {
int min = top();
int temp;
Iterator<Integer> it = stack.iterator();
while(it.hasNext()){
temp=it.next();
if(temp<min)
min=temp;
}
return min;
}
}