【LeetCode41-50】找出丢失最小正整数,计算蓄水量,检测?*匹配(44),跳跳棋,全排列,矩阵逆转,颠倒字母重新排序(auto,set/multiset,vector初始化),n次方

41.找出丢失的最小正整数

Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

要求用固定大小的空间,以及O(n)


我的解法一:

//添加了辅助项0,后来发现这个方法时间复杂度是O(nlogn),重新做的方法见解法二:

class Solution {
public:
    int firstMissingPositive(vector& nums) {
        nums.push_back(0);//加一项0为了确保为避免【-5,100】这种情况会输出-4
        sort(nums.begin(),nums.end());
        if(nums.size()<1||nums[0]>1)return 1;
        for(int i=1;i1&&nums[i-1]>=0)return nums[i-1]+1;
        }
          return nums[nums.size()-1]+1;  
        }
};


解法二://用到了unordered_map...这下时间复杂度变成了O(n)了…

class Solution {
public:
    int firstMissingPositive(vector& nums) {
        unordered_mapmapping;
        for(int i=0;i



42.计算蓄水容量

Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

我的解法:【击败了60%】

解决思路:找到最高的板子,那么填满之后肯定是一个不降的序列以及一个不增的序列组成,对应填满即可。

注意,比较大小std::max(t1,t2)   要加上std不然报错……尴尬

class Solution {
public:
    int trap(vector& height) {
        //思路:找到最高的,然后就是标准的先升再降了
        int result=0;
        int max=0,location=0;
        for(int i=0;imax){
                max=height[i];
                location=i;
            }
        }
        int begin=0;
        //升序的算一下
        for(int i=0;ilocation;--i){
            begin=std::max(height[i],begin);
            if(height[i]


43.两个字符串表示的数字相乘


规则:长度都小于110,包括0-9,头部不为0,不能直接转为int


我的解法://很单纯地一位一位拆开算了…用了倒置解决了相加的问题,再用加实现了乘……【只击败了0.38%的人】

注意string的倒置的reverse也是要reverse(string.begin(),string.end());

class Solution {
public:
	string multiply(string num1, string num2) {
		string result = "";
		if(num1=="0"||num2=="0")return "0";
		// num2.reverse();
		reverse(num2.begin(), num2.end());//再次强调,reverse是STL里的,不是string的成员函数
		string zero = "";
		for (int i = 0; i

别人的不需要reverse的简洁的解法://我还是太耿直了

//用num1[i]-'0'表示大小确实挺方便

//又看了一遍,确实精巧,和我们算乘法反的,但好简洁……

string multiply(string num1, string num2) {
    string sum(num1.size() + num2.size(), '0');
    
    for (int i = num1.size() - 1; 0 <= i; --i) {
        int carry = 0;
        for (int j = num2.size() - 1; 0 <= j; --j) {
            int tmp = (sum[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0') + carry;
            sum[i + j + 1] = tmp % 10 + '0';
            carry = tmp / 10;
        }
        sum[i] += carry;
    }
    
    size_t startpos = sum.find_first_not_of("0");
    if (string::npos != startpos) {
        return sum.substr(startpos);
    }
    return "0";
}


44.检测是否匹配(? * 匹配,做了好久,过阵子要在看看,DP搜索肯定方便点)

?可以代表一个字母,*可以代表任意长度的字母

isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false

终于做完了……花了好久好久……【击败了75%】


我的做法:把所有*提取出来,再分段检测匹配是否一样…同时要写一个isSame函数检测两个不含有*的string是否匹配

class Solution {
public:
	bool isSame(string s, string p) {
		if (p.size() == 0 && s.size() == 0)return true;
		if (s.size() == p.size()) {
			for (int i = 0; istar;
		for (int i = 0; i

45.跳跳棋

每个int代表下一步可以往后运动的步长,下面这种只击败了0.61%

class Solution {
public:
    int jump(vector& nums) {
        int result=1;
        if(nums.size()==0||nums.size()==1)return 0;
        for(int i=0;inums,int begin,int end){
        int result=begin;
        for(int i=begin;i

46.找出全排列//next_permutations

例如

[1,2,3] have the following permutations:

[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]

class Solution {
public:
    vector> permute(vector& nums) {
        vector>result;
        sort(nums.begin(),nums.end());
        if(nums[0]==nums[nums.size()-1]){result.push_back(nums);return result;}//防止【1】这种情况
        int flag=nums[0];int goon=1;
        while(1){
            result.push_back(nums);
            next_permutation(nums.begin(),nums.end());
            if(nums[0]!=flag)goon=0;
            if(nums[0]==flag&&goon==0)break;
        }
        return result;
    }

};


47.返回所有的全排列(这回可能有重复)

//但是我做上一题的时候貌似就包括可能有重复的情况,所有代码和上一题一样就通过了……


class Solution {
public:
    vector> permuteUnique(vector& nums) {
        vector>result;
        sort(nums.begin(),nums.end());
        if(nums[0]==nums[nums.size()-1]){result.push_back(nums);return result;}//防止【1】这种情况
        int flag=nums[0];int goon=1;
        while(1){
            result.push_back(nums);
            next_permutation(nums.begin(),nums.end());
            if(nums[0]!=flag)goon=0;
            if(nums[0]==flag&&goon==0)break;
        }
        return result;
    }
};

48.矩阵顺时针旋转90度


class Solution {
public:
    void rotate(vector>& matrix) {
        int size=(matrix.size()+1)/2;
        int length=matrix.size()-1;
        for(int i=0;i


49.颠倒字母重新分组 //auto,set/multiset,以及multiset给vector赋值

着重关注,这里用到了用法 auto, set/multiset<类型> , 以及Vector的另一种初始化……利用multiset给vector初始化……

class Solution {
public:
	vector> groupAnagrams(vector& strs) {
		unordered_map>mapping;
		for (int i = 0; i>result;
		for (auto m : mapping) {
				//这里的返回的是std::pair,第一个代表前面的,第二个代表后面的
			//下面是Vector<类型>的另一种初始化方式  temp(另一个)
			vector temp  (m.second.begin(), m.second.end());
			result.push_back(temp);
		}
		return result;
	}
};

50.计算pow(x,n) //n次方


这里要注意,n可能为负的!!!

class Solution {
public:
	double myPow(double x, int n) {
		if (n == 0) return 1;
		double t = myPow(x, n / 2);
		if (n % 2) {
			return n<0 ? 1 / x*t*t : x*t*t;
		}
		else {
			return t*t;//少计算了一次myPow,碉堡
		}
	}
};


如果用下面这段代码:

class Solution {
public:
	double myPow(double x, int n) {
		if (n == 1 )return x;
		if (n == -1)return 1 / x;
		if(n==0)return 1;
		//二分法
		return myPow(x, n / 2)*myPow(x, n - n / 2);
	}
};

下面的例子会超时间 0.00001 2147483647

所以上面的还是很厉害的……


最近题目做得少了…………


【LeetCode41-50】找出丢失最小正整数,计算蓄水量,检测?*匹配(44),跳跳棋,全排列,矩阵逆转,颠倒字母重新排序(auto,set/multiset,vector初始化),n次方_第1张图片

你可能感兴趣的:(LeetCode)