常见算法题(五)——剑指offer

剑指offer部分笔试题

算法博客暂时不更新了,更多内容可去leetcode,牛客网查看

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

如果不要求顺序,那么可以使用从两边开始的双指针,向中间夹,然后交换两数;本题要求原来的顺序,那么思路就是找到第一个奇数,拿出来,把前面所有数后移一位,当然注意边界,利用一个indexl=-1来存储最后一个奇数的索引,若第一个数是奇数,索引++=0,新插入的奇数从++index开始

  import java.util.Scanner;

     public class Solution {

     public static void main(String [] args) {
            Scanner sc = new Scanner(System.in);
            Solution ad = new Solution();
            int n = sc.nextInt();
            int[] array = new int[n];

            for(int i=0;i<n;i++) {
                array[i] = sc.nextInt();
            }
            sc.close();
            ad.reOrderArray(array);
            for(int i=0;i<n;i++) {
                System.out.println(array[i]);
            }

      }
     public void reOrderArray(int [] array) {
      int index = -1;
         for(int i=0;i<array.length;i++) {
            if(array[i]%2!=0) {
                if(i>0) {
                    int temp = array[i];
                    while(i-1>index) {
                        array[i] = array[i-1];
                        i--;
                    }
                    array[++index] = temp;
                }else {
                    index++;
                }   
            }
        }
     }

    }

反转链表

反转链表,再顺序输出。反转关键在于,第一个结点的next保存为temp,next指向新表头一开始head=null,然后head=p,p=temp

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

从两个表的表头分别比较即可,小的插入新链表

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

先判断B是不A的树顶,不是判断是不是A左子树树顶,不是判断是不是右子树树顶,其实就是递归,主要就是判断是否是树顶的条件为根相等,左子树相等&&右子树相等

public void createTree(TreeNode parent,int index,int flag) {
        if(flag==1) {
            if(index>array.length/2-1) {
                return;
            }
            if(array[index*2+1].equals("#")) {
                parent.left=null;
            }else {
                int num1 = Integer.parseInt(array[index*2+1]);
                TreeNode left = new TreeNode(num1);
                parent.left = left;
                createTree(left,index*2+1,1);
            } 

            if(array[index*2+2].equals("#")) {
                parent.right=null;
            }else {
                int num2 = Integer.parseInt(array[index*2+2]);
                TreeNode right = new TreeNode(num2);
                parent.right = right;
                createTree(right,index*2+2,1);
            } 
        }else {
            if(index>child.length/2-1) {
                return;
            }
            if(child[index*2+1].equals("#")) {
                parent.left=null;
            }else {
                int num1 = Integer.parseInt(child[index*2+1]);
                TreeNode left = new TreeNode(num1);
                parent.left = left;
                createTree(left,index*2+1,1);
            } 

            if(child[index*2+2].equals("#")) {
                parent.right=null;
            }else {
                int num2 = Integer.parseInt(child[index*2+2]);
                TreeNode right = new TreeNode(num2);
                parent.right = right;
                createTree(right,index*2+2,2);
            } 
        }   

    }

    public boolean HasSubtree(TreeNode root1,TreeNode root2) {
        if(root1==null||root2==null) return false;

        boolean flag = false;
        flag = isSame(root1,root2);
        if(!flag) {
            flag = HasSubtree(root1.left,root2);
        }
        if(!flag) {
            flag = HasSubtree(root1.right,root2);
        }
        return flag;
    }

    //判断r2是不是r1的树顶
    public boolean isSame(TreeNode r1,TreeNode r2) {
        if(r1==null&&r2!=null) return false;
        if(r2==null) return true;
        if(r1.val==r2.val) {
            return isSame(r1.left,r2.left)&&isSame(r1.right,r2.right);
        }else {
            return false;
        }
    }

    }

    class TreeNode{
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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

每次顺时针遍历一圈,分为→ ↓ ← ↑,循环条件为row>2*y&&colum>2*x,每次起点为00 11 22 33..注意边界即可

 public ArrayList<Integer> printMatrix(int [][] matrix) {
        ArrayList<Integer> list = new ArrayList<>();
        int i=0;
        int j=0;
        int row = matrix.length;
        int colum = matrix[0].length;
        //遍历一圈
        while(row>2*j&&colum>2*i) {
            for(int k=i;k<colum-i;k++) {
                list.add(matrix[i][k]);
            }   
            if(i+1<row-i) {
                for(int k=i+1;k<row-i;k++) {
                    list.add(matrix[k][colum-i-1]);
                }
            }
            if(colum-i-2>=j&&row-i-1>i) {
                for(int k=colum-i-2;k>=j;k--) {
                    list.add(matrix[row-1-i][k]);
                }
            }
            if(row-i-2>=i+1&&j<colum-i-1) {
                for(int k=row-i-2;k>=i+1;k--) {
                    list.add(matrix[k][j]);
                }
            }
            ++i;
            ++j;
        }
        return list;
    }

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同

找到第一个大于根节点的,则左边全是左子树,右边全部是右子树,比较左子树的根节点和右子树根结点注意边界(后序二叉搜索树)

public boolean VerifySquenceOfBST(int [] sequence) {
         if(sequence.length==1) return true;
            int index = -1;
            for(int i=0;i<sequence.length-1;i++) {
                if(sequence[i]>sequence[sequence.length-1]) {
                    index = i;
                    break;
                }
            }
            int root = sequence[sequence.length-1];
            //只有左子树
            if(index==-1) {
                int l = sequence[sequence.length-2];
                if(l<root) {
                    int[] s = Arrays.copyOfRange(sequence, 0, sequence.length-1);
                    return VerifySquenceOfBST(s);
                }else {
                    return false;
                }
            }
            //只有右子树
            if(index==0) {
                int r = sequence[sequence.length-2];
                if(r>root) {
                    int[]s = Arrays.copyOfRange(sequence, index, sequence.length-1);
                    return VerifySquenceOfBST(s);
                }else {
                    return false;
                }
            }else{
                int l = sequence[index-1];
                int r = sequence[sequence.length-2];
                if(l<root&&r>root) {
                    int[]s1 = Arrays.copyOfRange(sequence, 0, index);
                    int[]s2 = Arrays.copyOfRange(sequence, index, sequence.length-1);
                    return VerifySquenceOfBST(s1)&&VerifySquenceOfBST(s2);
                }else {
                    return false;
                }
            }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值