剑指Offer刷题记录11-20

11.二进制中1的个数
12.数值的整数次方
13.调整数组顺序使奇数位于偶数前面
14.链表中倒数第K个节点
15.反转链表
16.合并两个排序的链表
17.树的子结构
18.二叉树的镜像
19.顺时针打印矩阵
20.包含min函数的栈

11.二进制中1的个数

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

     public static int NumberOf1(int n) {
         String x=Integer.toBinaryString(n);
         int m=0;
         for(int i=0;i

如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在整数最右边的1就会变为0,原来在1后面的所有的0都会变成1(如果最右边的1后面还有0的话)。其余所有位将不会受到影响。
举个例子:一个二进制数1100,从右边数起第三位是处于最右边的一个1。减去1后,第三位变成0,它后面的两位0变成了1,而前面的1保持不变,因此得到的结果是1011.我们发现减1的结果是把最右边的一个1开始的所有位都取反了。这个时候如果我们再把原来的整数和减去1之后的结果做与运算,从原来整数最右边一个1那一位开始所有位都会变成0。如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作。

 public static int NumberOf2(int n) {
         int count=0;
         while(n!=0){
             count++;
             n=n&(n-1);
         }
         return count;
     }

12.数值的整数次方

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

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

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
方法一
1.要想保证原有次序,则只能顺次移动或相邻交换。
2.i从左向右遍历,找到第一个偶数。
3.j从i+1开始向后找,直到找到第一个奇数。
4.将[i,...,j-1]的元素整体后移一位,最后将找到的奇数放入i位置,然后i++。
5.终止条件:j向向后遍历查找失敗。

       public void reOrderArray(int [] a) {
           if(a==null||a.length==0)
               return;
           int i=0,j;
           while(i=i;k--){
                       a[k+1]=a[k];
                   }
                   a[i++]=tmp;
               }else{//查找失败
                   break;
               }
           }
       }
               
       boolean isEven(int n){
           if(n%2==0)
               return true;
           return false;
       }

方法二
整体思路:
首先统计奇数的个数
然后新建一个等长数组,设置两个指针,奇数指针从0开始,偶数指针从奇数个数的末尾开始 遍历,填数

 public void reOrderArray2(int [] a) {
           if(a.length==0||a.length==1)
               return;
           int oddCount=0,oddBegin=0;
           int b[]=new int[a.length];
           for(int i=0;i

14.链表中倒数第K个节点

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

//公共部分
    public class ListNode {
        int val;
        ListNode next = null;

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

方法一:两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指正走(k-1)步,到达第k个节点。然后两个指针同时往后移动,当第一个结点到达末尾的时候,第二个结点所在位置就是倒数第k个节点了

    public ListNode FindKthToTail(ListNode head,int k){
        if(head==null||k<=0)
            return null;
        ListNode pre=head;
        ListNode last=head;
        for(int i=1;i

方法二:全部进栈然后出栈第k个

    public ListNode FindKthToTail2(ListNode head,int k) {
        if(head==null||k<=0)
            return null;
        Stack stack=new Stack<>();
        ListNode node=head;
        while(node!=null){          
            stack.push(node);
            node=node.next;
        }
        if(k>stack.size())
            return null;
        while(k!=1&&!stack.isEmpty()){
            stack.pop();
            k--;
            
        }
        return stack.pop();  
     }

15.反转链表

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

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

        ListNode(int val) {
           this.val = val;
        }
    }
    
    public ListNode ReverseList(ListNode head) {
        if(head==null)
            return null;
        ListNode pre=null;
        ListNode next=null;      
        while(head!=null){
            next=head.next;
            head.next=pre;
            pre=head;
            head=next;
        }
        return pre;
    }

16.合并两个排序的链表

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

    public class ListNode {
        int val;
        ListNode next = null;
        ListNode(int val) {
           this.val = val;
        }
    }

非递归方法

       public ListNode Merge(ListNode list1,ListNode list2) {
           ListNode head=new ListNode(-1);
           head.next=null;
           ListNode root=head;
           while(list1!=null&&list2!=null){
               if(list1.val

递归方法

       public ListNode Merge(ListNode list1,ListNode list2) {
           if(list1==null)
               return list2;
           else if(list2==null)
               return list1;
           ListNode mergeHead=null;
           if(list1.val

17.树的子结构

输入两棵二叉树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 boolean HasSubtree(TreeNode root1,TreeNode root2) {
           boolean result=false;
           if(root1!=null&&root2!=null){
               if(root1.val==root2.val){
                   result=DoesTree1HaveTree2(root1,root2);
               }
               if(!result)
                   result=HasSubtree(root1.left, root2);
               if(!result)
                   result=HasSubtree(root1.right, root2);
           }
           return result;
        }
     
     public boolean DoesTree1HaveTree2(TreeNode root1,TreeNode root2){
         if(root1==null&&root2!=null)
             return false;
         if(root2==null)
             return true;
         if(root1.val!=root2.val)
             return false;
         return DoesTree1HaveTree2(root1.left, root2.left)&&DoesTree1HaveTree2(root1.right, root2.right);
     }

18.二叉树的镜像

剑指Offer刷题记录11-20_第1张图片
     public void Mirror(TreeNode root){
         if(root==null)
             return;
         if(root.left==null&&root.right==null)
             return;
         TreeNode pTemp=root.left;
         root.left=root.right;
         root.right=pTemp;
         if(root.left!=null)
             Mirror(root.left);
         if(root.right!=null)
             Mirror(root.right);
     }

19.顺时针打印矩阵

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

       public ArrayList printMatrix(int [][] array) {
           ArrayList result=new ArrayList();
           if(array.length==0)
               return result;
           int n=array.length,m=array[0].length;
           if(m==0)
               return result;
           int layers=(Math.min(n, m)-1)/2+1;
           for(int i=0;i=i)&&(n-i-1!=i);k--)//右到左
                   result.add(array[n-i-1][k]);
               for(int j=n-i-2;(j>i)&&(m-i-1!=i);j--)//左上到左下
                   result.add(array[j][i]);
           }
           return result;
        }

20.包含min函数的栈

定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

    private Stack data=new Stack();
    private Stack min=new Stack();
    Integer temp=null;
    public void push(int node) {
            if(temp!=null){
                if(node<=temp){
                    temp=node;
                    min.push(node);
                }
                data.push(node);
            }else{
                temp=node;
                data.push(node);
                min.push(node);
            }
        }
        
        public void pop() {
            int num=data.pop();
            int num2=min.pop();
            if(num!=num2)
                min.push(num2);
        }
        
        public int top() {
            return data.peek();
        }
        
        public int min() {
            return min.peek();
        }

你可能感兴趣的:(剑指Offer刷题记录11-20)