剑指offer(1)

数组:二位数组中的查找

题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

 1 class Solution {
 2 public:
 3     bool Find(vector<vector<int> > array,int target) {
 4         //从右上角开始找
 5         /*int row=0;
 6         int column = array[0].size()-1;
 7         while(row<array.size() && column>=0)
 8         {
 9             int num = array[row][column];
10             if(target ==num)
11                 return true;
12             else if(target > num)
13                 row++;
14             else
15                 column--;
16         }
17         return false;*/
18         //从左下角开始找
19         /*int row = array.size()-1;
20         int col = 0;
21         while(row>=0 && col<array[0].size())
22         {
23             int num = array[row][col];
24             if(target == num)
25                 return true;
26             else if(target > num)
27                 col++;
28             else
29                 row--;
30         }
31         return false;*/
32         //利用二分找,在每一行中利用二分查找
33         for(int i=0;i<array.size();i++)
34         {
35             int low = 0;
36             int high = array[0].size()-1;
37             int mid;
38             while(low<=high)
39             {
40                 mid = low+(high-low)/2;
41                 int num = array[i][mid];
42                 if(num == target)
43                     return true;
44                 else if(target>num)
45                     low = mid+1;
46                 else
47                     high = mid-1;
48             }
49         }
50         return false;
51     }
52 };
View Code

 

代码的完整性

数值的整数次方

题目描述:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

class Solution {
public:
    double Power(double base, int exponent) {
        if(exponent == 0)//指数为0值为1,0的0次方为1
            return 1;
        if(base == 0)//底数为0均为0
            return 0;
        double sum = 1;
        int n = (exponent>0)? exponent:-exponent;//要考虑底数为负,值为小数的情况
        while(n--)
        {
            sum *= base; 
        }
        return (exponent>0)? sum:(1/sum);
    }
};
View Code

调整数组顺序使奇数位于偶数前面

题目描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        if(array.size() == 0 || array.size() == 1)
            return;
        //第一种:用空间换时间
       /* vector<int> arr;
        for(int i=0;i<array.size();i++)
        {
            if(array[i]%2 == 1)
                arr.push_back(array[i]);
        }
        for(int i=0;i<array.size();i++)
        {
            if(array[i]%2 == 0)
                arr.push_back(array[i]);
        }
        for(int i=0;i<array.size();i++)
        {
            array[i] = arr[i];
        }*/
        //第二种,找到一个奇数就向它的前面去找偶数进行替换,注意相对位置不能变
        //因为是从开始往后依次找奇数的,所以当前找的奇数的前面的偶数都在它与前一个奇数之间
        int i,j;
        for(i=0;i<array.size();i++)
        {
            if(array[i]%2 == 1)
            {
                int temp = array[i];
                j=i-1;
                while(j>=0&&array[j]%2==0){
                    array[j+1]=array[j];
                    j--;
                }
                array[j+1]=temp;
            }
        }
    }
};
View Code

代码的鲁棒性

链表中倒数第k个结点

题目描述:输入一个链表,输出该链表中倒数第k个结点。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
            val(x), next(NULL) {
    }
};*/
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {   
        //第一种就是两个指针,相差k个距离,一起向后走,直到最后
        if(pListHead == NULL || k <= 0)
            return NULL;
        /*ListNode *p = pListHead;
        ListNode *q = pListHead;
        int i=0;
        //走到第k个
        for(;i<k&&q!=NULL;i++){
            q = q->next;            
        }
        if(i<k)//判断链是不是没有k个数
            return NULL;
        while(q != NULL){
            p = p->next;
            q = q->next;
        }
        return p;*/
        //通过对整体计数,查看是否不小于k,小于则返回空,否则就从头开始走count-k步
        int count = 0;
        ListNode *p = pListHead;
        while(p!=NULL){
            p = p->next;
            count++;
        }
        if(count < k) return NULL;
        int n = count - k;
        p = pListHead;
        while(n--){
            p = p->next;
        }
        return p;
    }
};
View Code

 反转链表

题目描述:输入一个链表,反转链表后,输出链表的所有元素。

 1 /*
 2 struct ListNode {
 3     int val;
 4     struct ListNode *next;
 5     ListNode(int x) :
 6             val(x), next(NULL) {
 7     }
 8 };*/
 9 class Solution {
10 public:
11     ListNode* ReverseList(ListNode* pHead) {
12         if(pHead==NULL || pHead->next == NULL)
13             return pHead;
14         ListNode* p = pHead;
15         ListNode* q = pHead->next;
16         p->next = NULL;//注意要头指针的next赋值为空
17         ListNode* w = NULL;
18         while(q)
19         {
20             w = q->next;
21             q->next = p;
22             p = q;
23             q = w;
24         }
25         return p;
26     }
27 };
View Code

 合并两个链表

题目描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

 1 struct ListNode {
 2     int val;
 3     struct ListNode *next;
 4     ListNode(int x) :
 5             val(x), next(NULL) {
 6     }
 7 };
 8 //非递归版本
 9 class Solution {
10 public:
11     ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
12     {
13         if(pHead1 == NULL )
14             return pHead2;
15         else if(pHead2 == NULL)
16             return pHead1;
17         ListNode* pHead=NULL;
18         ListNode* p=NULL;
19         if(pHead1->val <= pHead2->val)
20         {
21             pHead = pHead1;
22             pHead1 = pHead1->next;
23         }    
24         else
25         {
26             pHead = pHead2;
27             pHead2 = pHead2->next;
28         }
29         p = pHead;
30         while(pHead1!=NULL && pHead2!=NULL)
31         {
32             if(pHead1->val <= pHead2->val)
33             {
34                 p->next = pHead1;
35                 p = p->next;
36                 pHead1 = pHead1->next;
37             }    
38             else
39             {
40                 p->next = pHead2;
41                 p = p->next;
42                 pHead2 = pHead2->next;
43             }
44         }
45         if(pHead1 != NULL)
46             p->next = pHead1;
47         if(pHead2 != NULL)
48             p->next = pHead2;
49         return pHead;
50     }
51 };
52 
53 //递归版本
54 ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
55 {
56     if(pHead1 == NULL )
57         return pHead2;
58     else if(pHead2 == NULL)
59         return pHead1;
60     ListNode* pHead=NULL;
61     if(pHead1->val <= pHead2->val)
62     {
63         pHead = pHead1;
64         pHead1 = pHead1->next;
65         pHead->next = Merge(pHead1,pHead2);
66     }    
67     else
68     {
69         pHead = pHead2;
70         pHead2 = pHead2->next;
71         pHead->next = Merge(pHead1,pHead2);
72     }
73    return pHead;
74 }
View Code

树的子结构

题目描述:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

 1 struct TreeNode {
 2     int val;
 3     struct TreeNode *left;
 4     struct TreeNode *right;
 5     TreeNode(int x) :
 6             val(x), left(NULL), right(NULL) {
 7     }
 8 };
 9 //看了别人的写的,没想到用||和&&来判断
10 class Solution {
11 public:
12     bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2)
13     {
14         if(pRoot1 == NULL ||pRoot2 == NULL)
15             return false;
16         return Subtree(pRoot1,pRoot2) || HasSubtree(pRoot1->left,pRoot2) || HasSubtree(pRoot1->right,pRoot2);
17     }
18     bool Subtree(TreeNode* pRoot1, TreeNode* pRoot2)
19     {
20         if(pRoot2 == NULL)
21             return true;
22         if(pRoot1 == NULL)
23             return false;
24         if(pRoot1->val == pRoot2->val)
25             return Subtree(pRoot1->left,pRoot2->left) && Subtree(pRoot1->right,pRoot2->right);
26         else
27             return false;
28     }
29 };
View Code

面试思路:二叉树的镜像

题目描述:操作给定的二叉树,将其变换为源二叉树的镜像。 

输入描述:
二叉树的镜像定义:源二叉树 
    	    8
    	   /  \
    	  6   10
    	 / \  / \
    	5  7 9 11
    	镜像二叉树
    	    8
    	   /  \
    	  10   6
    	 / \  / \
    	11 9 7  5
 1 struct TreeNode {
 2     int val;
 3     struct TreeNode *left;
 4     struct TreeNode *right;
 5     TreeNode(int x) :
 6             val(x), left(NULL), right(NULL) {
 7     }
 8 };
 9 class Solution {
10 public:
11     void Mirror(TreeNode *pRoot) {
12         if(pRoot == NULL)
13             return;
14         //递归
15         /*if(pRoot->left!=NULL || pRoot->right!=NULL)
16         {
17             TreeNode* temp = pRoot->left;
18             pRoot->left = pRoot->right;
19             pRoot->right = temp;
20             Mirror(pRoot->left);
21             Mirror(pRoot->right);
22         }*/
23         //非递归
24         stack<TreeNode*> st;
25         st.push(pRoot);
26         while(!st.empty())
27         {
28             TreeNode* node = st.top();
29             st.pop();
30             if(node->left!=NULL || node->right!=NULL)
31             {
32                 TreeNode* temp = node->left;
33                 node->left = node->right;
34                 node->right = temp;
35             }
36             if(node->left)
37                 st.push(node->left);
38             if(node->right)
39                 st.push(node->right);
40         }
41     }
42 };
View Code

画图让抽象形象化:顺时针打印矩阵

题目描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 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.

 1 class Solution {
 2 public:
 3     vector<int> printMatrix(vector<vector<int> > matrix) {
 4         vector<int> res;
 5         int row = matrix.size();
 6         int col = matrix[0].size();
 7 
 8         if(row==0 || col==0)
 9             return res;
10         /*int left=0,right=col-1,top=0,bottom=row-1;
11         while(left<=right &&top<=bottom)
12         {
13             for(int i=left;i<=right;i++)
14                 res.push_back(matrix[top][i]);
15             for(int i=top+1;i<=bottom;i++)
16                 res.push_back(matrix[i][right]);
17             if(top!=bottom)//防止横向重复
18                 for(int i=right-1;i>=left;i--)
19                     res.push_back(matrix[bottom][i]);
20             if(left!=right)//防止纵向重复
21                 for(int i=bottom-1;i>top;i--)
22                     res.push_back(matrix[i][left]);
23             left++;
24             right--;
25             top++;
26             bottom--;
27         }*/
28         int circle = ((row<col?row:col)-1)/2+1;//圈数
29         for(int i=0;i<circle;i++)
30         {
31             for(int j=i;j<=col-1-i;j++)
32                 res.push_back(matrix[i][j]);
33             for(int k=i+1;k<=row-1-i;k++)
34                 res.push_back(matrix[k][col-1-i]);
35             for(int l=col-1-i-1;l>=i && i!=row-1-i;l--)//注意判断的时候一定不要判断错重复的条件
36                 res.push_back(matrix[row-1-i][l]);
37             for(int m=row-1-i-1;m>i && i!=col-1-i;m--)
38                 res.push_back(matrix[m][i]);
39         }
40         return res;
41     }
42 };
View Code

 举例让抽象具体化:包含min函数的栈

题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

 1 class Solution {
 2 public:
 3     //使用两个stack,是为了使当pop出一个数值的时候,min中的top依旧是当前数据中的最小值
 4     //每次push的时候都会将当前的最小值push进min中
 5     void push(int value) {
 6         data.push(value);
 7         if(mindata.empty())
 8             mindata.push(value);
 9         else
10         {
11             int val = mindata.top();
12             val<=value?mindata.push(val):mindata.push(value);
13         }
14 
15     }
16     void pop() {
17         data.pop();
18         mindata.pop();
19     }
20     int top() {
21         return data.top();//记得写return
22     }
23     int min() {
24         return mindata.top();
25     }
26 private:
27     stack<int> data;
28     stack<int> mindata;
29 };
View Code

 

 

posted on 2016-08-16 15:11  羽溪夜  阅读(150)  评论(0编辑  收藏  举报

导航