剑指offer编程题

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

解析:当输入数据n时,n与n-1进行按位与操作之后,可以实现消去n的二进制中的一个1,例如10的二进制位1010,9的二进制为1001,按位与之后为1000,那么我们一共进行了多少次的与操作,就相当于其对应的二进制中有多少位1。

class Solution {
public:
     int  NumberOf1(int n) {
       //n与n-1按位与,会消去低位的一个1
         //如:1010和1001
         int count=0;//记录1的个数
         while(n!=0){
             count++;
            n = n&(n-1);//每进行一次该操作就消去一个1
         }
         return count;
     }
};

二、 

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

解析:该题的难度不大,但是我在计算的时候却有忽略的地方,忽略掉exponent的多种情况

exponent的取值:

 

  • 正整数
  • 负整数
  • 为0
class Solution {
public:
    double Power(double base, int exponent) {
        int i,j;
        double fact=1.0;
        if(exponent>0)
        { //当指数为正整数时   
          for(i=0;i<exponent;i++)
          {
             fact=fact*base; 
          }
          return fact;
       }
       else if (exponent==0)  return 1;//当指数为0时
       else{//当指数为负整数时
            for(j=0;j<-exponent;j++)
            {
                fact=fact*base;
            }
            return 1.0/fact;
        }
        
    }
};

三、

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

解析:我的实现方法较复杂,额外的使用了两个容器,一个存放偶数,一个存放奇数。再将原array的容器清空,先push_back存放奇数的容器,再push_back存放偶数的容器。

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        int len=array.size();
        int i,j;
        vector<int> array2;
        vector<int> array3;
        for(i=0;i<len;i++){
            if(array[i]%2==0){//元素为偶数时
               array2.push_back(array[i]);
            }
            else array3.push_back(array[i]);//元素为奇数时
        }
        int len2=array2.size();
        for(j=0;j<len2;j++){
            array3.push_back(array2[j]);
        }
       array.erase(array.begin(),array.end());
        int len3=array3.size();
        for(int k=0;k<len3;k++){
            array.push_back(array3[k]);
        }
    }
};

下面介绍较为简单的实现方式:

没有想到该方式是因为,忽略了容器之间是可以直接赋值的

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        vector<int> a;
        int len=array.size();
        for(int i=0;i<len;i++){
            if(array[i]%2==1){//为奇数时
                a.push_back(array[i]);
            }
        }
        for(int j=0;j<len;j++){//为偶数时
            if(array[j]%2==0){
                a.push_back(array[j]);
            }
        }
        array=a;
        
    }
};

四、

输入一个链表,输出其倒数第k个节点

分析:使用两个指针,让p指针先于q指针走k-1步。然后两个指针同时移动,直至p->next!=NULL。因为p指针只能位于最后的位置处。

注意一定要判断所给的链表是否为空,所给的k值是否有效

struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if(pListHead==NULL||k==0)//如果该链表为空,或者k值无效时
            return NULL;
        ListNode *p=pListHead;
        ListNode *q=pListHead;
        unsigned int n=k-1;//让p指针比q指针先走k-1步
        while(n>0){ 
            if(p->next != NULL)
               p=p->next;
            else{
                return NULL;
            }
            n--;
        }
        while(p->next !=NULL){//一定要注意p指针只能走到最后一个节点,判断条件
            p=p->next;
            q=q->next;
        }
        return q;
    }
};

输入一个链表,反转链表后,输出链表的新表头

解析:该题采用头插法就可以实现,需要注意的是,原链表的头结点是否带有数据

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {//根据定义可知,每个节点都是携带有数据的
	}
};*/
class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == NULL) return NULL;
         ListNode *p=pHead->next;
        ListNode *q=p;
         pHead->next=NULL;
        while(p!=NULL){//头结点也是携带数据的,头插法
            q=p->next;
            p->next=pHead;
            pHead=p;
            p=q;
        }
        return pHead;
    }
};

char 字符型与string字符串型的区别

1、char字符型相当于一个数组,每个单元存放一个字符,而string类型则是存放一整个字符串,并且以‘\0’结尾。

2、string类可调用的函数:

  • s.append("字符串 ")
  • s1.swap(s2)
  • int i=s.find('l',0)//从位置0开始寻找l出现的位置,并返回该位置
  • s.length()
  • s.empty()

六、

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。
由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

解析:该题难度不大,但要综合考虑可能出现的情况,主要由以下几种情况:

(1)容器的大小为0时,返回0

(2)容器中只有一个元素时,返回值应为1

(3)容器中的元素大于1时,先对容器中的元素进行排序,再使用循环来处理

  • 当numbers[i]==numbers[i+1]时,count加1,直至count>len/2时退出循环,返回numbers[i]
  • 当numbers[i]!=numbers[i+1]时,count要重置为1,重新开始计数             
class Solution {
public:
    int MoreThanHalfNum_Solution(vector<int> numbers) {
        int len=numbers.size();
        int i;
        int count=1;
        sort(numbers.begin(),numbers.end());
        if(len==1)//当元素个数为1时,无法进行下面的循环
            return 1;
        for(i=0;i<len-1;i++)//当元素个数大于1时,
        {
            if(numbers[i]==numbers[i+1])
              count++;
            if(numbers[i]!=numbers[i+1])
            {count=1;
            continue;}
            if(count>len/2) 
                return numbers[i];
        }
         return 0;
    }
};

 七、

输入n个整数,找出其中最小的k个整数,例如输入4,5,1,6,2,7,3,8,则最小的4个数字为1,2,3,4

解析:

要考虑到极端的情况,当输入的k值过大时,超过了容器的大小时,这时应返回的是一个空容器

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution{
public:
	vector<int> GetMin(vector<int> input,int k){
	    int len=input.size();
        int i;
        vector<int> a;
        sort(input.begin(),input.end());
        if(k<=len)
		{
           for(i=0;i<k;i++)
		   {
            a.push_back(input[i]);
            }
        }
        return a;
    }
};
int main(){
	Solution obj;
	vector<int> b;
	vector<int> c;
	int i;
	int a[7]={1,3,5,2,8,6,4};
	for(i=0;i<7;i++){
		b.push_back(a[i]);
	}
	c=obj.GetMin(b,4);
	for(int j=0;j<4;j++)
	   cout<<c[j]<<" ";
	system("pause");
	return 0;
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值