• 算法学习之剑指offer(三)


    题目1

    题目描述

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

    如果一个整数不为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 class Solution {
        public int NumberOf1(int n) {
    		int count = 0;
            while(n!=0){
                count++;
                n = n&(n-1);
            }
            return count; 
        }
    }

    题目2

    题目描述

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

    考虑下0和负数的情况即可

    public class Solution {
        public double Power(double base, int exponent) {
            double result = 1.00;
            
            for(;exponent>0;exponent--)
            	result*=base;
            
            if(exponent<0){
                for(;exponent<0;exponent++)
            		result*=base;
                return 1/result;
            }
            
            return result;
      }
    }

    题目3

    题目描述

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

    记得是要导包的,时间复杂度和空间复杂度都是O(n)

    import java.util.*;
    public class Solution {
        public void reOrderArray(int [] array) {
            int []test = Arrays.copyOf(array,array.length);
            int index=0;
            for(int i=0;i<test.length;i++){
                if(test[i]%2==1){
    				array[index]=test[i];
                    index++;
                }
            }
            for(int i=0;i<test.length;i++){
                if(test[i]%2==0){
    				array[index]=test[i];
                    index++;
                }
            }
        }
    }
    题目4

    题目描述

    输入一个链表,输出该链表中倒数第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 node1 = head;
            ListNode node2 = head;
    		for(int i=0;i<k-1;i++)
            {
                if(node1.next==null)
                    return null;
                node1 = node1.next;
            }
            
            while(node1.next!=null){
                node1 = node1.next;
                node2 = node2.next;
            }
            
            return node2;
            
        }
    }
    题目5

    题目描述

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

    自己的做法(两个指向,一个用来遍历一个用来保存)+自己基础上更简单的+ 递归的方法

    /*
    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 last_node=null;//上一个为空
            ListNode node = head;
            
            while(node.next!=null)
            {
                //保存下一个的位置
                ListNode next = node.next;
                //进行逆转修改,并保存当前节点为上一个节点
                node.next = last_node;
                last_node = node;
                //遍历跳转至下一个
                node = next;
            }
            node.next=last_node;//最后一次逆转修改
            return node;
        }
    }
    
    public ListNode ReverseList(ListNode head) {
        ListNode pre = null;
        ListNode next = null;
        while (head != null) {
            next = head.next;
            head.next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }
    

    递归解法

    /*
    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;
             
            //不断化解为更小的head.next链表逆转
            ListNode pReverseNode=ReverseList(head.next);
             
            head.next.next=head;//将下个节点的next设置为自己,层层调用之后就会全部逆转了
            head.next=null;//虽然每层head.next都职位null了,但其实只是为了最后一个节点可以置为null 
             
            return pReverseNode;//此处无论调用到多少层,返回的都是原链表最后一个
        }
    }

    题目6

    题目描述

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

    简单的递归解法(还有复杂的非递归方法):

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


  • 相关阅读:
    STL源码剖析:迭代器
    STL源码剖析:配置器
    [bzoj3940][Usaco2015 Feb]Censoring
    [bzoj2212][Poi2011]Tree Rotations
    [bzoj2733]永无乡&&[bzoj3545]Peaks
    挂个AC自动机
    [bzoj4237]稻草人
    莫比乌斯反演定理证明
    斜率优化dp学习
    备忘
  • 原文地址:https://www.cnblogs.com/chz-blogs/p/9380933.html
Copyright © 2020-2023  润新知