软件工程10道题
1.爬楼梯:斐波那契数列的算法
class Solution {
public:
/**
* @param n: An integer
* @return: An integer
*/
int climbStairs(int n) {
// write your code here
int fib1=1;
int fib2=2;
if(n==0)
{
return 1;
}
if(n==1)
{
return 1;
}
if(n==2)
{
return 2;
}
if(n>1)
{
for(int i=2;i<n;i++)
{
fib2=fib1+fib2;
fib1=fib2-fib1;
}
return fib2;
}
}
};
2.排列序号:对原数组中的每一个位置,找到其后有多少个数比它小,由于字典排序是从小到大排列的,所以只需计算出第i位(从1开始)在它后面比它小的数进行(A.size()-k-1)!,最后相加即可。
class Solution {
public:
/**
* @param A an integer array
* @return a long integer
*/
long long permutationIndex(vector<int>& A) {
// Write your code here
int i,j;
long n=1;
for(i=0;i<A.size();i++)
{
for(j=i+1;j<A.size();j++)
{
if(A[i]>A[j])
{
long m=1;
for(int k=i;A.size()-k-1>0;k++)
{
m=m*(A.size()-k-1);
}
n=n+m;
}
}
}
return n;
}
};
3.合并排序数组:先将两个数组合并,然后将B数组里的元素与A里面的比较,然后将B的元素插入进去。
class Solution {
public:
/**
* @param A and B: sorted integer array A and B.
* @return: A new sorted integer array
*/
vector<int> mergeSortedArray(vector<int> &A, vector<int> &B) {
// write your code here
vector<int> C(A.size()+B.size(), 0);
int i,j;
for(i=0;i<A.size();i++)
{
C[i]=A[i];
}
int f;
f=i;
for(j=0;j<B.size();j++)
{
C[i]=B[j];
i++;
}
int p=0;
for(f;f<i;f++)
{
for(j=0;j<A.size()+p;j++)
{
if(C[f]<C[j])
{
int m,k;
k=C[f];
m=f;
while(m>j)
{
C[m]=C[m-1];
m--;
}
C[j]=k;
p++;
}
}
}
return C;
}
};
4.翻转链表:翻转链表最简单的方式是改变链的链接顺序,把后一个节点的next变成前一节地址。
/**
* Definition of ListNode
*
* class ListNode {
* public:
* int val;
* ListNode *next;
*
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param head: The first node of linked list.
* @return: The new head of reversed linked list.
*/
ListNode *reverse(ListNode *head) {
// write your code here
ListNode *prev=NULL;
while(head!=NULL)
{
ListNode *t=head->next;
head->next=prev;
prev=head;
head=t;
}
return prev;
}
};
5.乘积最大子序列:用Min表示以nums[i]结尾乘积最小的连续子序列 因为有负数,所以保存这个是必须的
class Solution {
public:
/**
* @param nums: a vector of integers
* @return: an integer
*/
int maxProduct(vector<int>& nums) {
// write your code here
int Max = nums[0];
int Min = nums[0];
int allMax = nums[0];
for(int i=1;i<nums.size();i++)
{
int premax = Max;
int premin = Min;
Max = max(nums[i],max(nums[i]*premax,nums[i]*premin));
Min = min(nums[i],min(nums[i]*premax,nums[i]*premin));
allMax=max(allMax,Max);
}
return allMax;
}
};
//自己写的第一种但复杂度过高
/*
int i,j,k,m;
k=nums[0];
for(i=0;i<nums.size();i++)
{
m=1;
if(k<nums[i])
{
k=nums[i];
}
for(j=i;j<nums.size();j++)
{
m=m*nums[j];
if(k<m)
{
k=m;
}
}
}
return k;
*/
6.解码方法:斐波那契数列,我们用两个变量fib2, fib1来分别表示s[i-1]和s[i-2]的解码方法,然后我们从i=1开始遍历,也就是字符串的第二个字符,我们判断如果当前字符为'0',说明当前字符不能单独拆分出来,只能和前一个字符一起,fib2=fib1,然后我们看前面的字符,如果前面的字符是1或者2时,我们就可以更新,fib2=fib2+fib1,其实fib1赋值为之前的fib2,如果不满足这些条件的话,那么fib1=fib2。
class Solution {
public:
/**
* @param s a string, encoded message
* @return an integer, the number of ways decoding
*/
int numDecodings(string& s) {
// Write your code here
int fib1=1,fib2=1;
if (s.empty()||s.front()=='0')
{
return 0;
}
for(int i=1;i<s.size();i++)
{
if(s[i]=='0')
{
if(s[i-1]=='1'||s[i-1]=='2')
{
fib2=fib1;
}
else
return 0;
}
else if(s[i-1]=='1'||(s[i-1]=='2'&&s[i]<='6'))
{
int t;
t=fib2;
fib2=fib2+fib1;
fib1=t;
}
else
{
fib1=fib2;
}
}
return fib2;
}
};
7.两个链表的交叉:利用栈。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
/**
* @param headA: the first list
* @param headB: the second list
* @return: a ListNode
*/
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
// write your code here
stack<ListNode *> A,B;
ListNode *x=NULL;
if(headA==NULL||headB==NULL)
{
return NULL;
}
else
{
for(;headA!=NULL;headA=headA->next)
{
A.push(headA);
}
for(;headB!=NULL;headB=headB->next)
{
B.push(headB);
}
for(;A.top()!=NULL&&B.top()!=NULL;)
{
if(A.top()==B.top())
{
x=A.top();
A.pop();
B.pop();
}
else
{
break;
}
}
return x;
}
}
};
8.N皇后问题:
class Solution {
public:
/**
* Get all distinct N-Queen solutions
* @param n: The number of queens
* @return: All distinct solutions
* For example, A string '...Q' shows a queen on forth position
*/
vector<vector<string> > solveNQueens(int n) {
// write your code here
vector<vector<string> > ret;
search(0,n,ret);
return ret;
}
int c[20];
void search(int r,int &n, vector<vector<string>> &ret)
{
if(r == n)
{
vector<string> v;
for(int i=0; i<n; ++i)
{
string s ="";
for(int j=0; j<n; j++)
{
if(j==c[i])
{
s+='Q';
}
else
{
s+='.';
}
}
v.push_back(s);
}
ret.push_back(v);
}
for(int i=0; i<n; i++){
c[r] = i;
int ok = 1;
for(int j=0; j<r; j++)
if(c[r]==c[j] || r-j==c[r]-c[j] || r-j==c[j]-c[r]){
ok = 0;
break;
}
if(ok) search(r+1,n,ret);
}
}
};
9.全排列:可以理解为每个数在开头时后面所有数的全排列,以此类推进行递归。
class Solution {
public:
/**
* @param nums: A list of integers.
* @return: A list of permutations.
*/
vector<vector<int> > permute(vector<int> nums) {
// write your code here
vector<vector<int> > result;
int size = nums.size();
permute(nums, 0, size, result);
return result;
}
void permute(vector<int> &nums, int begin, int end, vector<vector<int> > &result)
{
if(begin == end)
{
result.push_back(nums);
}
else
{
for(int i=begin; i<end; i++)
{
int temp = nums[i];
nums[i] = nums[begin];
nums[begin] = temp;
permute(nums, begin+1, end, result);
temp = nums[i];
nums[i] = nums[begin];
nums[begin] = temp;
}
}
}
};
10.翻转字符串:定义两个整形变量,如果s[i]不为空其中一个减一,另一个不变,变量之差即为单词长度。
class Solution {
public:
/**
* @param s : A string
* @return : A string
*/
string reverseWords(string s) {
// write your code here
string word, line;
int size=s.size();
int i=size-1, j, wordbegin=size-1, wordend=size-1;
if(s.empty())
{
return s;
}
for(;i>=0;)
{
for(;s[i]==' '&&i>=0;i--)
{
wordbegin--;
wordend--;
}
for(;s[i]!=' '&&i>=0;i--)
{
wordbegin--;
}
word.resize(0);
for(j=wordbegin+1; j<=wordend; j++)
{
word.append(1,s[j]);
}
if(wordbegin==0)
{
line=line+word;
}
else
{
line=line+word+" ";
}
wordend =wordbegin;
}
return line;
}
};