《面试准备》刷题记录

题目1:数组循环右移 将一个长度为n的数组A的元素循环右移k位比如 数组 1, 2, 3, 4, 5 循环右移3位之后变成 3, 4, 5, 1, 2

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

int* func(int a[],int n,int k){
    k=k%n;
    static int b[5];
    if(k==0)
        return a;
    else{
        for(int j=0;j<n;j++,k++){
            b[k%n] = a[j];
        }
    }
    return b;
}

int main(void){
    int a[5]={1,2,3,4,5};
    int *p=func(a,5,3);
    for(int i=0;i<5;i++){
        cout<<p[i]<<" ";
    }
    return 0;
}


题目2:给定一个整形数组和一个整数target,返回2个元素的下标,它们满足相加的和为target。你可以假定每个输入,都会恰好有一个满足条件的返回结果。 时间复杂的O(n)

Example: 
Given nums = [2, 7, 11, 15], target = 9
return [0, 1]. Because nums[0] + nums[1] = 2 + 7 = 9, 

#include <iostream>
#include <unordered_map>
using namespace std;
/**
给定一个整形数组和一个整数target,返回2个元素的下标,它们满足相加的和为target。
你可以假定每个输入,都会恰好有一个满足条件的返回结果。**/
int main(){
    int nums[3] = {3,2,4}, target = 6;
    unordered_map<int,int>map;
    unordered_map<int,int>::iterator it;

    for(int i=0;i<3;map[nums[i]]=i,i++){   //注意不要自己找自己
        it = map.find(target - nums[i]);
        if(it==map.end())
            continue;

        if(it!=map.end()){
            cout<<it->second<<" "<<i<<endl;
            break;
        }
    }
    if(it==map.end())
        cout<<"not exist"<<endl;
    return 0;
}

题目3:给定一个数组,找出其中所有不同的三数和等于0的组合。

例如:

nums[7] = {-1,0,1,2,0,4,-2};

return  [-1 0 1]    [-2,0,2]

首先解给定一个数组,找出其中所有不同的2数和等于0的组合(前后指针方法)。时间复杂度O(n)

#include <iostream>
#include <algorithm>
#include <unordered_set>
using namespace std;

int main(){
    int nums[7] = {-1,0,1,2,0,4,-2};
    sort(nums,nums+6);
    int *f = nums;
    int *r = nums+6;
    unordered_set<int>myset;
    while(f!=r){
        if(*f+*r==0){
             myset.insert(*f); //去重
             f++;
        }
        else if(*f+*r>0)
            r--;
        else
            f++;
    }
    for(auto it=myset.begin();it!=myset.end();it++){
        cout<<*it<<" "<<-(*it)<<endl;
    }
    return 0;
}

再来说三个数,思路和上面一样,只是先固定一个数,使另外两个数的和等于该数的相反数。时间复杂的O(n^2)

#include <iostream>
#include <unordered_set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

vector<vector<int>> threeSum(vector<int> &nums) {
    int target;
    vector<vector<int>> ans;
    sort(nums.begin(), nums.end());
    for (int i = 0; i < nums.size(); i++) {
        if (i > 0 && nums[i] == nums[i - 1])    //target去重
            continue;
        if ((target = nums[i]) > 0)             //target小于0不玩了
            break;
        int l = i + 1, r = nums.size() - 1;     //l=i+1原因是不跟自己玩
        while (l < r) {
            if (nums[l] + nums[r] + target < 0)
                ++l;
            else if (nums[l] + nums[r] + target > 0)
                --r;
            else {
                ans.push_back({target, nums[l], nums[r]});
                ++l, --r;
                while (l < r && nums[l] == nums[l - 1])    //l去重
                    ++l;
                while (l < r && nums[r] == nums[r + 1])    //r去重
                    --r;
            }
        }
    }
    return ans;
}

int main(){
    vector<int>v;
    for(int i=-8;i<10;i++){
        v.push_back(i);
    }
    vector<vector<int>> sss;
    sss = threeSum(v);
    for(int i=0;i<sss.size()/3;i++){
        for(int j=0;j<3;j++)
            cout<<sss[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}


题目4:给定一个数组,求取其中的有最大和的子数组(子数组表示连续元素构成的序列),时间复杂度O(n)

例如:输入5个数,大小分别为:-3 6 -2 7 -4,则最大子数组为6 -2 7,他们的和为11. 

#include <iostream>
#include <unordered_map>
using namespace std;

int main(){
    int b[7]={-2,3,-5,6,-4,9,-2};
    int sum = 0,max = -10001;
    for(int i=0;i<7;i++){
        sum += b[i];
        if(sum>max)
            max = sum;
        if(sum<0)
            sum = 0;
    }
    cout<<max<<endl;
    return 0;
}

题目5:给定一个数组,求取其中的有最大和的上升子数组(子数组表示连续元素构成的序列),时间复杂度O(n)

例如:比如输入6个数,大小分别为: 10 5 6 -2 7 8,则最大上升子数组为7 8,他们的和为15.

#include <iostream>
#include <unordered_map>
using namespace std;

int main(){
    int b[7]={5,-2,3,5,6,4,9};
    int tmp,sum = 0,max = -10001;
    for(int i=0;i<7;i++){
        if(b[i]<tmp||sum<0)  //<改为>为最大下降子数组
            sum = 0;
        sum += b[i];
        if(sum>max)
            max = sum;
        tmp = b[i];
    }
    cout<<max<<endl;
    return 0;
}

题目6:给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 :

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。这种写法很好理解(滑动窗口思想)。

#include <iostream>
#include <unordered_set>
#include <unordered_map>
using namespace std;

int lengthOfLongestSubstring1(string s) {
    unordered_set<char> t;
    int res = 0, left = 0, right = 0;
    while (right < s.size()) {
        if (t.find(s[right]) == t.end()) {
            t.insert(s[right++]);
            res = max(res, (int)t.size());
        }  else {
            t.erase(s[left++]);
        }
    }
    return res;
}
//效率更高
int lengthOfLongestSubstring2(string s) {
    int res = 0, left = 0, i = 0, n = s.size();
    unordered_map<char, int> m;
    for (int i = 0; i < n; ++i) {
        left = max(left, m[s[i]]);
        m[s[i]] = i + 1;
        res = max(res, i - left + 1);
    }
    return res;
}

int main(){
    string s = "pwewkewkpew";
    cout<<lengthOfLongestSubstring2(s)<<endl;
    return 0;
}

题目7:给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 :

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案

#include <iostream>
#include <unordered_set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

string huiwen(string s){
    int max = 0;
    string res;
    for(int i=0;i<s.length();i++){
        int l = i,r=s.length()-1,back = s.length()-1;
        if(max>r-l)              //减枝
            return res;
        while(l<r){
            if(s[l]==s[r]){
                l++;
                r--;
            }else{
                l = i;
                r = --back;
            }
        }
        if(max < l+r-2*i+1){
            max = l+r-2*i+1;
            res = s.substr(i,l+r-2*i+1);
        }
    }
    return res;
}

int main(){
    string s = "abababbaba";
    cout<<huiwen(s)<<endl;
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值