【LeetCode51-60】N皇后,和最大子串,螺旋矩阵,跳跳棋,合并区间,第K个全排列

51.N-皇后问题


有N 个皇后放在NXN的棋盘上,要求互相之间一步不能吃到……


我的思路:定义了四种规则,对应了皇后的四种走法,利用unordered_map存储(好像效率并没有很高,直接往前搜寻应该更节约空间时间)

横着竖着很好理解,斜着只要保证i+j以及i-j不一样即可。

接着用递归,递归的时候注意把修改值再修改回来……


class Solution {
public:
	vector> solveNQueens(int n) {
		unordered_maprule1, rule2, rule3, rule4;
		//1.行,2.列,3.左斜,4.右斜
		vector>result;
	/*	vectorresult_one;
		vector>result;
		for (int i = 0; i < n; ++i) {
			string temp ;
			for (int j = 0; j < n; ++j)temp+=".";
			result_one.push_back(temp);
		}*/
		std::vector result_one(n, std::string(n, '.'));
	
		solve(result,result_one, n, 0,rule1,rule2,rule3,rule4);
		return result;
	}


bool solve(vector>&result, vector&result_one,int n, int m, unordered_map&rule1, unordered_map&rule2, unordered_map&rule3, unordered_map& rule4) {
	if (m >= n) {
		result.push_back(result_one); 
		return true;
	}
		for (int i = 0; i < n; ++i) {
			if (rule1[m]==0 && rule2[i]==0 && rule3[i + m]==0 && rule4[i - m]==0) {
				result_one[m][i] += 35;
				rule1[m]++; rule2[i]++; rule3[i + m]++; rule4[i - m]++;
				solve(result,result_one, n, m + 1, rule1, rule2, rule3, rule4);
				rule1[m]--; rule2[i]--; rule3[i + m]--; rule4[i - m]--;
				result_one[m][i] -=35;
			}
		}
		return false;
	}

};


53.N-皇后问题的解的个数


上一体的解法稍微修改下即可……

class Solution {
public:
    int totalNQueens(int n) {
        unordered_maprule1, rule2, rule3, rule4;
        int result=0;

		solve(result, n, 0,rule1,rule2,rule3,rule4);
		return result;
    }
    bool solve(int &result,int n, int m, unordered_map&rule1, unordered_map&rule2, unordered_map&rule3, unordered_map& rule4) {
	if (m >= n) {
		result++;
		return true;
	}
		for (int i = 0; i < n; ++i) {
			if (rule1[m]==0 && rule2[i]==0 && rule3[i + m]==0 && rule4[i - m]==0) {
				rule1[m]++; rule2[i]++; rule3[i + m]++; rule4[i - m]++;
				solve(result, n, m + 1, rule1, rule2, rule3, rule4);
				rule1[m]--; rule2[i]--; rule3[i + m]--; rule4[i - m]--;
			}
		}
		return false;
	}

    
};


53.找出和最大的子串

/


//之前有一道类似的题目,如果没有正的就输出0,这次要输出负的了

程序如下:

//关键就是一个判断是否大于0停止循环 //但只几百了3%的人……

class Solution {
public:
    int maxSubArray(vector& nums) {
        int result=-2147483648;
        
        for(int i=0;iresult||nums[i]>0){
                int temp=nums[i];
                result=std::max(result,temp);
                int j=i+1;
                while(temp>0&&j


解法二:运用DP动态规划,击败了一半的人,而且。。很简洁……


这里*max_element用了STL里的找最大值的功能!!!有空一定要整理下STL相关功能!!

class Solution {
public:
    int maxSubArray(vector& nums) {
        
     //用DP试试
     for(int i=1;i0?nums[i-1]:0;
     }
     return *max_element(nums.begin(),nums.end());



    }
};


54.螺旋矩阵

[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
You should return  [1,2,3,6,9,8,7,4,5] .

贪吃蛇占满整个屏幕的那种感觉(Spiral是回旋的意思)


这里注意一下Vector用这个初始化更方便了,免得push_back....

		vectorresult((right + 1)*(bottom + 1));

所以知道空间大小,就直接给开辟了吧!!!


class Solution {
public:
	vector spiralOrder(vector>& matrix) {
		vectorresult;
		int left = 0,  head = 0, bottom =matrix.size()-1;
		if(bottom==-1)return result;//防止空输入,不然matrix[0]就出错了……
		int right = matrix[0].size()-1;

		int flag = 0;
		while (left <= right&&head <= bottom) {
			if (flag == 4)flag = 0;
			switch (flag) {
			case 0:for (int i = left; i <= right; ++i)result.push_back(matrix[head][i]); head++; break;
			case 1:for (int i = head; i <= bottom; ++i)result.push_back(matrix[i][right]); right--; break;
			case 2:for (int i = right; i >= left; --i)result.push_back(matrix[bottom][i]); bottom--; break;
			case 3:for (int i = bottom; i >= head; --i)result.push_back(matrix[i][left]); left++; break;
			}
			flag++;
		}
		return result;
	}
};


55.跳跳棋,判断能不能到末尾


还是那个思路,给每一位加上i

只要考虑所有为0的位置,看前面有没有能越过这一位的……如果没有就输出false即可……

class Solution {
public:
	bool canJump(vector& nums) {
		for (int i = 0; i1 && nums[0] == 0)return false;
		for (int i = 1; i

56.merge intervals(合并区间)



For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].



这里有Sort结构体的用法:

sort(ins.begin(),ins.end(), [](Interval a, Interval b){return a.start < b.start;});


以及vector的最后一位为  XXX.back()



 bool cmp(Interval a, Interval b) {
	 return a.start < b.start;
 }
class Solution {
public:
	vector merge(vector& intervals) {
		sort(intervals.begin(), intervals.end(), cmp);
		vectorresult;
		if(intervals.size()==0)return {};
		result.push_back(intervals[0]);
		for(int i=1;iresult.back().end)result.push_back(intervals[i]);
		    else result.back().end=std::max(result.back().end,intervals[i].end);
		}
		
		return result;
}
};


57.Insert Interval(嵌入区间)


直接调用上一条的结果就能击败41%的人了……


/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
    vector insert(vector& intervals, Interval newInterval) {
        intervals.push_back(newInterval);
        
        return merge(intervals);
    }
    
    vector merge(vector& intervals) {
		sort(intervals.begin(), intervals.end(), [](Interval a,Interval b){return a.startresult;
		if(intervals.size()==0)return {};
		result.push_back(intervals[0]);
		for(int i=1;iresult.back().end)result.push_back(intervals[i]);
		    else result.back().end=std::max(result.back().end,intervals[i].end);
		}
		
		return result;
}
};


58.返回最后一个词的长度


For example, 
Given s = "Hello World",
return 5.

、、陷阱在于最后几位可能都是空格......

class Solution {
public:
    int lengthOfLastWord(string s) {
        int end=s.size()-1;
        for(int i=s.size()-1;i>=0;i--){
            if(s[i]==' '){
                if(end-i==0){end--;}
                else return end-i;
            }
        }
        return end+1;
    }
};


59.另一个螺旋矩阵(1-n²写入方阵)

Given n = 3,

You should return the following matrix:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]

class Solution {
public:
    vector> generateMatrix(int n) {
      vectora(n);//STL初始化vector方法,n个0
      vector< vector>result(n,a);//同理,初始化vector里的vector...
       
       // vector > result( n, vector(n) );
       int flag=0,left=0,right=n-1,up=0,down=n-1,ii=0;
       while(left<=right&&up<=down){
           if(flag==4)flag=0;
           switch(flag){
               case 0:for(int i=left;i<=right;++i)result[up][i]=++ii;up++;break;
               case 1:for(int i=up;i<=down;++i)result[i][right]=++ii;right--;break;
               case 2:for(int i=right;i>=left;--i)result[down][i]=++ii;down--;break;
               case 3:for(int i=down;i>=up;--i)result[i][left]=++ii;left++;break;
           }
           ++flag;
       }
       return result;
    }
};



60.输出全排列第K个序列


方法一,用到了vector里的next_permutation,因为很冗余,只击败了0.5%的人……

class Solution {
public:
    string getPermutation(int n, int k) {
        int rounds=1;
        vectornum;
        for(int i=1;i<=n;++i){rounds*=i;num.push_back(i);}
        k=k%rounds;if(k==0)k=rounds;
        for(int i=1;i

方法二  用了set以及递归,终于正常了

class Solution {
public:
    string getPermutation(int n, int k) {

        string result="";
        settemp;
        for(int i=1;i<=n;++i){temp.insert(i);}
        help(n,k,temp,result);
        return result;
    }
    string help(int n,int k,set&temp,string &result){
        if(n==0)return "";
        int rounds=1;
        for(int i=1;i<=n-1;++i){rounds*=i;}
        auto ii=temp.begin();
        for(int j=0;j<(k-1)/rounds;j++)++ii;
       int num=*ii;
        result+=to_string(num);
        temp.erase(num);
        help(n-1,k-(k-1)/rounds*rounds,temp,result);
        return result;
    }
    
};

别人家的方法三://有空了再看,图书馆闭关了,囧

string getPermutation(int n, int k) {
    int i,j,f=1;
    // left part of s is partially formed permutation, right part is the leftover chars.
    string s(n,'0');
    for(i=1;i<=n;i++){
        f*=i;
        s[i-1]+=i; // make s become 1234...n
    }
    for(i=0,k--;ii;j--)
            s[j]=s[j-1];
        k%=f;
        s[i]=c;
    }
    return s;
}


一天做了十道题,有点懵逼………//谢谢嘿嘿嘿陪我刷题到现在~


祝刷题愉快~












你可能感兴趣的:(LeetCode)