2017面试算法题

用堆解决最小k个数

/*class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        int len=input.size();
        if(len<=0||k>len||k<=0) return vector<int>();
         
        vector<int> res(input.begin(),input.begin()+k);
        //建堆
        make_heap(res.begin(),res.end());
         
        for(int i=k;i<len;i++)
        {
            if(input[i]<res[0])
            {
                //先pop,然后在容器中删除
                pop_heap(res.begin(),res.end());
                res.pop_back();
                //先在容器中加入,再push
                res.push_back(input[i]);
                push_heap(res.begin(),res.end());
            }
        }
        //使其从小到大输出
        sort_heap(res.begin(),res.end());
         
        return res;
         
    }
};*/
class Solution {
public:
    
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
          
        vector<int> result;
        if(input.size()==0||k==0||k>input.size()){
            return result;
        }
         for(int i=input.size()/2-1;i>=0;i--){//初始化堆
             
            adjustHeap(input,i,k);
        }
        int i=k;
        while(i<input.size()){
             
            if(input[0]>input[i]){
                  int temp=input[i];
                input[i]=input[0];
                input[0]=temp;
                adjustHeap(input,0,k);
                i=k;
            }else {
                i++;
            }
             
             
             
        }
 
      for(int i=0;i<k;i++){
           
          result.push_back(input[i]);
      }
           
        return result;
         
         
         
    }
     
    void adjustHeap(vector<int>&input,int i,int length){//堆调整
         
        int child=i*2+1;
        if(child<length){
             
            if(child+1<length&&input[child+1]>input[child]){
                child=child+1;
            }
            if(input[child]>input[i]){
                int temp=input[i];
                input[i]=input[child];
                input[child]=temp;
            adjustHeap(input,child,length);
            }
   
        }
    
    }
    void heapSort(vector<int>&input,int length){//堆排序
        for(int i=length/2-1;i>=0;i--){//初始化堆
             
            adjustHeap(input,i,length);
        }
         
        for(int i=length-1;i>0;i--){
                int temp=input[i];
                input[i]=input[0];
                input[0]=temp;
            adjustHeap(input,0,i);
             
        }
         
    }
     
};

倒置和删除字符串

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
 
int main()
{
    string s1,s2;
    getline(cin,s1);
    getline(cin,s2);
    for(int i=0;i<s2.length();i++)
    {
        int index;
        while ((index=s1.find(s2[i]))!=-1)
        {
            s1.erase(index,1);
        }
    }
    cout<<s1<<endl; 
    return 0;
}

#include <iostream>
#include <string.h>
 
using namespace std;
 
void reverse(char* start, char* end)
{
    while(start < end)
    {
        char temp = *start;
        *start = *end;
        *end = temp;
        start++;
        end--;
    }
}
 
int main()
{
    char input[1000];
    gets(input);
    // 翻转整个句子
    reverse(input, input + strlen(input) - 1);
    // 翻转单词
    char* start = input;
    while(*start != '\0')
    {
        char *end = start;
        while(*end != ' ' && *end != '\0')
            end++;
        reverse(start, end-1);
        if(*end != '\0')
            start = end + 1;
        else
            start = end;
    }
    cout<<input<<endl;
    return 0;
}

给你两个集合,要求{A} + {B}。 注:同一个集合中不会有两个相同的元素

#include<iostream>
#include<iterator>
#include<set>
  
using namespace std;
int main(void)
{
    int n, m;
    while (cin >> n, cin >> m)
    {
        set<int> st;
        int num;
        for (int i = 0; i < n + m; ++i)
        {
            cin >> num;
            st.insert(num);
        }
        int size = st.size();
        set<int>::iterator it = st.begin();
        for (int i = 0; i < size - 1; ++i)
        {
            cout << *it << " ";
            ++it;
        }
        cout << *it << endl;
    }
    return 0;
}

有一个X*Y的网格,要在此网格上从左上角到右下角,只能走格点且只能向右或向下走。请设计一个算法,计算小团有多少种走法。给定两个正整数int x,int y,请返回小团的走法数目。

/*动态规划:
     对于x*Y网格,dp[i][j]表示(i,j)位置一共有多少种走法,
     由于只能向左和向右走,所以第一列和第一行所有位置的走法都是1,即dp[i][0]=1,dp[0][j]=1(0=<i<=x,0<=j<=y),
     对于其他位置,走法应该等于其左边格点的走法和其上面格点的走法之和,dp[i][j]=dp[i-1][j]+dp[i][j-1],
     画个图比较容易理解。
*/  
#include<iostream>
#include<vector>
using namespace std;
 
int main()
{
    int x, y;
    cin >> x >> y;
    int dp[11][11];
    for (int j = 0; j <= y; j++)
        dp[0][j] = 1;
    for (int i = 0; i <= x; i++)
        dp[i][0] = 1;
    for (int i = 1; i <= x; i++)
    {
        for (int j = 1; j <= y; j++)
          {
             dp[i][j] = dp[i - 1][j] + dp[i][j-1];
          }
    }
    cout << dp[x][y] << endl;
}

合并相同price字段

#include <iostream>
 
using namespace std;
 
 
 
int main()
{
    int dataPrices[10000] = {0};
    int start, end, price;
    while(cin>>start>>end>>price)
    {
        int min = start, max = end;
        for(int i = start; i <= end; i++)
            dataPrices[i] = price;
        while(cin>>start>>end>>price)
        {
            min = min < start ? min : start;
            max = max > end ? max : end;
            for(int i = start; i <= end; i++)
                dataPrices[i] = price;
        }
         
        int status = 0,p_tmp;
        for(int i = min; i <= max; i++)
        {
            if(status ==0)
            {
                p_tmp = dataPrices[i];
                if(p_tmp !=0)
                {
                    cout<<"["<<i<<", ";
                    status = 1;
                }
            }
            if(p_tmp != dataPrices[i+1]&&p_tmp != 0)
            {
                cout<<i<<", "<<p_tmp<<"]";
                if(i != max)
                    cout<<",";
                status = 0;
            }
        }
    }
    return 0;
}

给定一个英文字符串,请写一段代码找出这个字符串中首先出现三次的那个英文字符

#include<iostream>
#include<cstdlib>
#include<string>
using namespace std;
int main()
{
    string s;
    while(getline(cin,s))         //获取一行的数据  接受一个字符串,可以接收空格并输出,需包含#include<string>
    {
        int hashtable[256]={0};
        for(int i=0;i<s.size();i++)
        {
            if(isalpha(s[i]))     //判断是不是字符
               hashtable[s[i]]++;
            if(hashtable[s[i]]==3)
            {
                cout<<s[i]<<endl;
                break;
            }
        }
    }
    return 0;
}
#include <iostream>
#include <string>
#include <map>
 
using namespace std;
 
int main(int argc, const char * argv[]) {
    map<char,int> letter;
    string s;
    getline(cin,s);
    int i=0;
    char l;
    while(i<s.length()-1){
        l = s[i++];
        if((l>='a'&&l<'z') || (l>='A'&&l<='Z')){
            letter[l]++;
            if(letter[l]==3){
                cout<<l<<endl;
                break;
            }
        }
    }
    return 0;
}
给定一个十进制的正整数number,选择从里面去掉一部分数字,希望保留下来的数字组成的正整数最大。输入325 1 输出35
#include<string>
#include<iostream>
using namespace std;
 
int main()
{
    string s;
    int len,i;
    while(cin>>s>>len){
        i=1;
        //len为需要删除的数的数量,用while循环判断
        while(len--){
            //slen为输出的数字的位数
            int slen = s.length();
            for(i=0;i<slen-1;i++){
                //找到第一个小于自己右边相邻数的数
                if(s[i]<s[i+1]){
                    //string的erase方法,删除下标为i的数
                    s.erase(s.begin()+i);
                    break;
                }
            }
            //由于slen-1在上面的for循环判断会越界,所以单独判断
            //当i为数组最后一个数时,删除最后一个数
            if(i==slen-1)  s.erase(s.end()-1);
        }
        cout<<s<<endl;
    }
    return 0;
}

处理环的问题,输入字符串,求含有ABCDE的最短子串。

#include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
int main(){
    string s;
    int i,j,num,len;
    while(cin>>s){
        len=s.length();
        s=s+s;
        i=0,j=0,num=0;
        int Min=len;
        map<char,int> book;
        while(true){
            while(i<s.length()&&num<5){
                if((s[i]=='A'||s[i]=='B'||s[i]=='C'||s[i]=='D'||s[i]=='E')
                    &&book[s[i]]++==0)
                    num++;
                i++;
            }
            if(num<5) break;
            Min=min(Min,i-j);
            if((s[j]=='A'||s[j]=='B'||s[j]=='C'||s[j]=='D'||s[j]=='E')
                &&--book[s[j]]==0) num--;
            j++;
        }
    cout<<len-Min<<endl;
    }
}//尺取法,求包含ABCDE的最短字串
给定一个句子(只包含字母和空格), 将句子中的单词位置反转,单词用空格分割, 单词之间只有一个空格,前后没有空格。 比如: (1) “hello xiao mi”-> “mi xiao hello”
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
 
int main() {
    string words;
    while (getline(cin, words)) {
        reverse(words.begin(), words.end());
        unsigned i = 0, j = i;
        while (i < words.size()) {
            while (i < words.size() && words[i] != ' ')
                ++i;
            reverse(words.begin() + j, words.begin() + i);
            j = ++i;
        }
        cout << words << endl;
    }
    return 0;
}

链表回文

class PalindromeList {
public:
    bool chkPalindrome(ListNode* A) {
        // write code here
        if(A==NULL)
            return false;
        else if(A->next==NULL)
            return true;
        //快慢指针找出中间节点
        ListNode* quick=A;
        ListNode* slow=A;
        while(quick!=NULL&&quick->next!=NULL)
        {
            quick=quick->next->next;
            slow=slow->next;
        }
        //反转
        ListNode* p=slow->next;
        ListNode* p1=p->next;       
        while(p!=NULL)
        {
            p->next=slow;
            slow=p;
            p=p1;
            p1=p1->next;
        }
         
        while(A!=slow)
        {
            if((A->val)!=(slow->val))
            {
                return false;
            }else{
                if(A->next==slow)
                {
                    return true;
                }
                A=A->next;
                slow=slow->next;
            }
        }
        return true;
         
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值