程序员面试金典2

1.魔术索引(1)

class MagicIndex {
public:
    bool findMagicIndex(vector<int> A, int n) {
        int len=A.size();
        if(len<=0||len!=n) return false;
        
        int left=0,right=len-1,mid;
        while(left<=right){
            mid=(left+right);
            if(A[mid]==mid)
                return true;
            else{
                if(A[mid]<mid)
                    left=mid+1;
                else right=mid-1;
            }
        }
        
        return false;
    }
};

切记二分查找是left<=right...

 

2.魔术索引2(切记抓住数据规律)

class MagicIndex {
public:
    bool findMagicIndex(vector<int> A, int n) {
        return find(A,A.size(),0,A.size()-1);
    }
    
private:
    bool find(vector<int>& data,const int& len,int left,int right){
        if(right<left||left<0||right>=len)
            return false;
        
        int mid=left+(right-left)/2;
        int midval=data[mid];
        if(midval==mid)
            return true;
        
        //搜索左半部分
        int leftindex=((mid-1)<midval)?(mid-1):midval;
        if(find(data,len,left,leftindex))
            return true;
        
        int rightindex=((mid+1)>midval)?(mid+1):midval;
        if(find(data,len,rightindex,right))
            return true;
        
        return false;
    }
};

 

3.机器人走方格

看着别人的思路,尽然能错n次,数组越界都不知道。。。无语

class Robot {
public:
    int countWays(vector<vector<int>> map, int x, int y) {

        if (x <= 0 || y <= 0 || x > 50 || y > 50)
            return -1;

        int i, j;
        long vec[51][51] = { 0 };

        //注意数值是否越界
        for (i = 0; i < x; i++)
        {
            if (map[i][0] != 1) break;
            else vec[i][0] = 1;
        }
        for (i = 0; i < y; i++)
        {
            if (map[0][i] != 1) break;
            else vec[0][i] = 1;
        }

        for (i = 1; i < x; i++)
        {
            for (j = 1; j < y; j++)
            {
                if (map[i][j] == 1)
                    vec[i][j] = (vec[i - 1][j] + vec[i][j - 1]) % 1000000007;
            }
        }
        return vec[x-1][y-1];
    }
};

 

4.硬币表示

没看懂,待后续进一步学习dp。。。

class Coins {
public:
    int countWays(int n) {
        if (n <= 0) return 0;
        else return getnum(n);
    }

private:
    int getnum(int n)
    {
        int i, j, tmp = 0, data[4] = { 25,10,5,1 };
        int dpcoin[100001] = { 0 };

        dpcoin[0] = 1;
        for (i = 0; i < 4; i++)
        {
            for (j = data[i]; j <= n; j++)
            {
                dpcoin[j] = (dpcoin[j] + dpcoin[j - data[i]]) % 1000000007;
            }
        }

        return dpcoin[n];
    }
};

 

3.输出单层二叉树节点

class TreeLevel {
public:
    ListNode* getTreeLevel(TreeNode* root, int dep) {

        if (NULL == root || dep < 0)
            return NULL;

        if (0 == dep) { //根节点判断
            ListNode *res = new ListNode(root->val);
            return res;
        }

        int nextlevel = 0, delnum = 1, depth = 1;
        ListNode *res = NULL, *pnode;
        queue<TreeNode*> sdata;
        sdata.push(root);

        while (!sdata.empty()) {

            TreeNode* tmp = sdata.front();
            if (depth == dep) {
                if (res == NULL) {
                    res = new ListNode(tmp->val);
                    pnode = res;
                }
                else {
                    ListNode* next = new ListNode(tmp->val);
                    pnode->next = next;
                    pnode = pnode->next;
                }
            }
            if (tmp->left != NULL) {
                ++nextlevel;
                sdata.push(tmp->left);
            }
            if (tmp->right != NULL) {
                ++nextlevel;
                sdata.push(tmp->right);
            }
            --delnum;sdata.pop();

            if (0 == delnum) {

                if (depth == dep)
                    break;  //指定层节点输出完毕

                ++depth;
                delnum = nextlevel;
                nextlevel = 0; //置零统计下一层数目
            }
        }
        return res;
    }
};

 

4.链式A+B

class Plus {
public:
    ListNode* plusAB(ListNode* a, ListNode* b) {

        if (NULL == a || NULL == b)
            return NULL;

        int val;
        bool sign = false;
        ListNode *tmp1 = a, *tmp2 = b, *res, *pnode;

        res = new ListNode(-1);pnode = res;

        while (tmp1&&tmp2)
        {
            if (sign)
                val = tmp1->val + tmp2->val + 1;
            else val = tmp1->val + tmp2->val;
            
            if (val >= 10) //确定是否需要进位
                sign = true;
            else sign = false;
            pnode->next = new ListNode(val % 10);
            pnode = pnode->next;

            tmp1 = tmp1->next;
            tmp2 = tmp2->next;
        }

        if (tmp1)
        {
            while (tmp1)
            {
                if (sign)
                    val = tmp1->val + 1;
                else val = tmp1->val;

                if (val >= 10)
                    sign = true;
                else sign = false;

                pnode->next = new ListNode(val % 10);
                pnode = pnode->next;
                tmp1 = tmp1->next;
            }
        }
        if (tmp2)
        {
            while (tmp2)
            {
                if (sign)
                    val = tmp2->val + 1;
                else val = tmp2->val;

                if (val >= 10)
                    sign = true;
                else sign = false;

                pnode->next = new ListNode(val % 10);
                pnode = pnode->next;
                tmp2 = tmp2->next;
            }
        }
        if (sign)
        {
            pnode->next = new ListNode(1);
        }

        pnode = res->next;
        delete res;
        return pnode;
    }
};

 

5.最小调整有序

有一个整数数组,请编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的。

注意:n-m应该越小越好,也就是说,找出符合条件的最短序列。

class Rearrange {
public:
    vector<int> findSegment(vector<int> A, int n) {

        vector<int> res(2,0);
        if (n != A.size()) return res;

        vector<int> sortvt(A);
        sort(sortvt.begin(), sortvt.end());

        int left = 0, right = n - 1;
        while (left <= n - 1)
        {
            if (sortvt[left] != A[left])
                break;
            else ++left;
        }
        if (left == n) //A为有序数组
            return res;

        while (right >= left)
        {
            if (sortvt[right] != A[right])
                break;
            else --right;
        }
        
        res[0] = left;
        res[1] = right;
        return res;
    }
};

 

你可能感兴趣的:(程序员面试金典2)