1.合并两个排序的链表:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
思路:不知道用循环行不行,自己编译的不能通过。确实递归的方法更好一些:
困惑:定义一个链表的变量不确定是声明一下,还是申请一下地址。
自己的程序没有ac:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
ListNode* res=NULL;
ListNode* head=res;
//ListNode* res=new ListNode*(pHead1);
// ListNode head=res(-1);
//if(pHead1==NULL&&pHead2==NULL)
// return NULL;
if(pHead1==NULL)
return pHead2;
if(pHead2==NULL)
return pHead1;
while(pHead1->next!=NULL&&pHead2->next!=NULL)
{
if(pHead1->val<=pHead2->val)
{
res->next=pHead1;
res=res->next;
pHead1=pHead1->next;
}
else{
res->next=pHead2;
res=res->next;
pHead2=pHead2->next;
}
}
return head;
}
};
用递归的方法做:
class Solution {
public:
ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
if(pHead1==NULL)
return pHead2;
if(pHead2==NULL)
return pHead1;
ListNode* res=NULL;
if(pHead1->val<=pHead2->val)
{
res=pHead1;
res->next=Merge(pHead1->next,pHead2);
}
else
{
res=pHead2;
res->next=Merge(pHead1,pHead2->next);
}
return res;
}
};
2.二进制中1的个数:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
思路:可以整数右移,但是有一个人正数和负数的问题。若是负数最高位是1.也可以1左移。(位与是&,与是&&)循环左移1,再与整数位与。(困惑:循环截至条件是1的左移的值,但是1是不断变大的,何时截至)思路3也可以整数减1之后再与原整数位与,然后原整数变为位与的结果值,循环。
思路2的程序:
class Solution {
public:
int NumberOf1(int n) {
unsigned int b=1;
int count=0;
while(b) //为什么是b就行
{
if(n&b) //这里没有区分&& 和&
count++;
b=b<<1;
}
return count;
}
};
3.顺时针打印矩阵:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
class Solution {
public:
vector<int> printMatrix(vector<vector<int> > matrix) {
vector<int> res;
int row=matrix.size();
int col=matrix[0].size();
if(row==0||col==0)
return res;
int left=0;
int right=col-1;
int top=0;
int dtn=row-1;
while(left<right&&top<dtn)
{
int i,j;
for(int i=top,j=left;j<right;j++)
res.push_back(matrix[i][j]);
if(top<dtn)
{
for(int j=right,i=top;i<dtn;i++)
res.push_back(matrix[i][j]);
}
if(left<right&&top<dtn)
{
for(int i=dtn,j=right;j>left;j--)
res.push_back(matrix[i][j]);
}
if(top<dtn&&left<right)
{
for(int i=dtn,j=left;i>top;i--)
res.push_back(matrix[i][j]);
}
left++,right--;
top++,dtn--;
}
return res;
}
};
4.按之字形顺序打印二叉树:请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
思路:我原先以为用栈和队都是可以的,队是先进先出,栈是后进先出,。但是用队的话,它的下一行就无法实现之字形打印,因为下一行完全是反方向的,不但结点是反方向而且左右子树也要是反方向,队不满足左右左右结点。而栈就符合这个性质,所以只能用栈。
<原先错误的程序用了队,编译不过>
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
queue<TreeNode*> q1,q2;
vector<vector<int>> res;
// vector<int> tmp;
// int flag=0;
vector<vector<int> > Print(TreeNode* pRoot) {
if(pRoot==NULL)
return res;
TreeNode* fr;
//int flag=0;
q1.push(pRoot);
// tmp.push_back(pRoot->val);
// res.push_back(tmp);
// tmp.clear();
while(q1.size()!=0||q2.size()!=0)
{
if(!q1.empty())
{
vector<int> tmp;
while(!q1.empty())
{
fr=q1.front();
tmp.push_back(fr->val);
q1.pop();
if(fr->right!=NULL)
{ q2.push(fr->right);
//tmp.push_back(fr->right->val);
}
if(fr->left!=NULL)
{q2.push(fr->left);
//tmp.push_back(fr->left->val);
}
}
res.push_back(tmp);
tmp.clear();
}
if(!q2.empty())
{vector<int> tmp;
while(!q2.empty())
{
fr=q2.front();
q2.pop();
if(fr->left!=NULL)
{ q1.push(fr->left);
//tmp.push_back(fr->left->val);
}
if(fr->right!=NULL)
{q1.push(fr->right);
// tmp.push_back(fr->right->val);
}
res.push_back(tmp);
tmp.clear();
}
}
}
return res;
}
};
用栈的程序(依然未通过,怀疑是tmp定义的位置不对):
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
// vector<int> tmp;
// int flag=0;
vector<vector<int> > Print(TreeNode* pRoot) {
stack<TreeNode*> q1,q2;
vector<vector<int>> res;
if(pRoot==NULL)
return res;
TreeNode* fr;
//int flag=0;
q1.push(pRoot);
// tmp.push_back(pRoot->val);
// res.push_back(tmp);
// tmp.clear();
while(q1.size()!=0||q2.size()!=0)
{
if(!q1.empty())
{
vector<int> tmp;
while(!q1.empty())
{
fr=q1.top();
tmp.push_back(fr->val);
q1.pop();
if(fr->right!=NULL)
{ q2.push(fr->right);
//tmp.push_back(fr->right->val);
}
if(fr->left!=NULL)
{q2.push(fr->left);
//tmp.push_back(fr->left->val);
}
}
res.push_back(tmp);
tmp.clear();
}
if(!q2.empty())
{vector<int> tmp;
while(!q2.empty())
{
fr=q2.top();
tmp.push_back(fr->val);
q2.pop();
if(fr->left!=NULL)
{ q1.push(fr->left);
//tmp.push_back(fr->left->val);
}
if(fr->right!=NULL)
{q1.push(fr->right);
// tmp.push_back(fr->right->val);
}
res.push_back(tmp);
tmp.clear();
}
}
}
return res;
}
};
5.二维数组中的查找:在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
思路:从左下往右上找,或从右上往左下找。
【错误的程序】
class Solution {
public:
bool Find(int target, vector<vector<int> > array) {
if(array.size()!=0)
{
int i,j;
int lsize=array[0].size()-1;
int hsize=array.size()-1; //刚知道求行数的方法
i=0;
j=lsize;
while(i>=0&&i<=hsize&&j>=0&&j<=lsize)
{
if(array[i][j]==target)
{
return true;
break;}
if(array[i][j]<target)
i++;
else if(array[i][j]>target)
j--;
}
return false;
}
}
};
6.数组中超过一半的数:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:用的土方法,先排序,再积累相同的。剑指offer书是用快速排序,但是也需要确定个数是否超过一半。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.empty())
return 0;
int len=numbers.size();
int len1=len>>1;
sort(numbers.begin(),numbers.end());
int num=0;
int temp=0;
for(int i=0;i<len;i++)
{
if(numbers[i]==temp)
num+=1;
else
{
num=0;
temp=numbers[i];
}
if(num>=len1)
{
return numbers[i];
break;
}
}
return 0;
}