算法学习之剑指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;
       }       
   }


原文地址:https://www.cnblogs.com/chz-blogs/p/9380933.html