11.二进制中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,就可以进行多少次这样的操作.
(注意:与是不是负数没有关系.每次都是把最右的1计算并清除,这样就只剩下其它的1,并且没有新加的1,所以和是不是负数无关!)
package com.matajie;
/**
* 11.二进制中1的个数
* 题目描述
* 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
*
* 我的程序才不会有bug!
* author:年仅18岁的天才少年程序员丶mata杰
**/
public class NumberOf1 {
public int NumberOf1(int n) {
int count = 0;
while (n != 0){
count++;
n = n & (n - 1);
}
return count;
}
}
12.数值的整数次方
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
思路:
进入这道题之间我们先了解一下什么是快速幂.
先举个栗子:我们想计算X8 : 我们如果一个一个往上乘需要进行7次运算.
(XX)(XX)(XX)(XX),用这种求法,先进行乘法得X2,再执行三次乘法,这样去计算,则乘法运算执行4次,所以为了快速计算整数幂,我们就会考虑这种思想.
整数快速幂计算XN:
package com.matajie;
/**
* 我的程序才不会有bug!
* author:年仅18岁的天才少年程序员丶mata杰
* 整数快速幂
* 用X^19举例,19转为二进制 10011;
* 1 0 0 1 1
*
* 初始: ans = 1, res = X;
*
* 1 : ans = res * ans = X;
* res = res * res = X^2;
*
* 1 : ans = res * ans = X^3;
* res = res * res = X^4;
*
* 0 : res = res * res = X^8;
*
* 0 : res = res * res = X^16;
*
* 1 : ans = res * ans = X^19;
* res = res * res = X^32;
**/
public class IntegerFastPower {
int QuickPow(int X, int N){
int res = X;
int ans = 1;
while (N != 0){
if ((N & 1) != 0){
ans *= res;
}
res *= res;
N =N>>1;
}
return ans;
}
}
以N = 19为例, 二进制表示为 10011, 二进制从右向左算,但乘出来顺序是X1 * X2 * X16是从左向右的,我们不断地让res *= res,目的就是累乘,以便随时对ans做出贡献, res * res = res2,下一步再乘就是res2 * res2 = res4,同理可得res ->res2 -> res 4 ->res 8 ->res16 -> … 我们发现指数正是2i,我们再看这个例子,X19=X1 * X2 * X16,这三项完美解决,这就是快速幂.
再回来看本题,就很简单了.(注意:int类型abs(INT_MIN)会溢出,所以用long.)
package com.matajie;
/**
* 12.数值的整数次方
* 题目描述
*
* 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
*
* 我的程序才不会有bug!
* author:年仅18岁的天才少年程序员丶mata杰
**/
public class Power {
public double Power(double base, int exponent) {
//int类型abs(INT_MIN)会溢出,所以用long.
long p = Math.abs((long) exponent);
double res = 1.0;
while (p != 0) {
if((p&1)!=0){
res *= base;
}
base *= base;
p = p >> 1;
}
return exponent<0?1/res:res;
}
}
13.调整数组顺序使奇数位于偶数前面
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
思路:(本题我的思路不太好,希望当有大神看到的时候可以指点一下qaq)
思路一:冒泡法:前偶后奇就交换.
package com.matajie;
/**
* 13.调整数组顺序使奇数位于偶数前面
* 题目描述
*
* 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
* 使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
*
* 我的程序才不会有bug!
* author:年仅18岁的天才少年程序员丶mata杰
**/
public class ReOrderArray {
public void reOrderArray(int [] array) {
int length = array.length;
for(int i = 0;i<length;i++){
for(int j = length-1;j>0;j--){
if(array[j] % 2 == 1 && array[j-1] % 2 == 0){
int temp = array[j];
array[j] = array[j-1];
array[j-1] = temp;
}
}
}
}
}
思路二:遍历这个数组得到哪些位置应该存奇数,哪些位置应该存偶数,然后再遍历这个数组,遇到奇数则依次放到奇数的位置,遇到偶数则依次放到偶数的位置.
package com.matajie;
/**
* 13.调整数组顺序使奇数位于偶数前面
* 题目描述
*
* 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
* 使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
*
* 我的程序才不会有bug!
* author:年仅18岁的天才少年程序员丶mata杰
**/
public class ReOrderArray {
public void reOrderArray(int [] array) {
int length = array.length;
int count = 0;
for(int i = 0;i<length;i++){
if(array[i] % 2 != 0){
count++;
}
}
int[] temp = new int[length];
int a = 0;
int b = count;
for (int j = 0;j<length;j++){
if(array[j] % 2 == 0){
temp[b++] = array[j];
}else {
temp[a++] = array[j];
}
}
for(int i = 0;i<length;i++){
array[i] = temp[i];
}
}
}
14.链表中倒数第K个节点
题目描述
输入一个链表,输出该链表中倒数第k个结点
思路(前后指针):
两个指针,先让第一个指针和第二个指针都指向头结点,然后再让第一个指针走(k-1)步,到达第k个节点,然后两个指针同时往后移动,当第一个指针到达末尾时,第二个指针所在位置即为倒数第k个节点.
package com.matajie;
/**
* 14.链表的倒数第k个节点
* 题目描述
* 输入一个链表,输出该链表中倒数第k个结点。
*
* 我的程序才不会有bug!
* author:年仅18岁的天才少年程序员丶mata杰
**/
public class FindKthToTail {
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public ListNode FindKthToTail(ListNode head,int k) {
ListNode front = head;
ListNode back = head;
int i;
for(i = 0;front != null && i<k;i++){
front =front.next;
}
if(front == null&&i < k){//k>链表长度,返回null
return null;
}else if(front == null){
return head;
}
while (front != null) {
front = front.next;
back = back.next;
}
return back;
}
}
15.反转链表
package com.matajie;
/**
* 15.反转链表
* 题目描述
* 输入一个链表,反转链表后,输出新链表的表头。
*
* 我的程序才不会有bug!
* author:年仅18岁的天才少年程序员丶mata杰
**/
public class ReverseList {
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public ListNode ReverseList(ListNode head) {
ListNode result = null;
ListNode cur = head;
while (cur != null){
ListNode next = cur.next;
//头插
cur.next = result;
result =cur;//头插结束
cur = next;
}
return result;
}
}