劍指offer(四)

31.整數中1出現的次數

在這裏插入圖片描述

class Solution {
public:
    int NumberOf1Between1AndN_Solution(int n)
    {
        int ret = 0;
        for(int i=1; i<=n; i++)
            ret += getOneCounts(i);
        
        return ret;
    }
    
private:
    int getOneCounts(int n)
    {
        int ret = 0;
        while(n > 0)
        {
            ret += (n%10==1)?1:0;
            n /= 10;
        }
        
        return ret;
    }
};

32.把數組排成最小的數

在這裏插入圖片描述

對數組進行排序
排序規則:

  • 將int a, int b轉爲string
  • 若 a+b<b+a a排在在前
class Solution {
public:
    string PrintMinNumber(vector<int> numbers) {
        
        sort(numbers.begin(), numbers.end(), cmp);
        
        string ret;
        for(int i=0; i<numbers.size(); i++)
        {
            ret += to_string(numbers[i]);
        }
        
        return ret;
    }
    
private:
    static bool cmp(int a, int b)
    {
        string n1 = to_string(a);
        n1 += to_string(b);
        
        string n2 = to_string(b);
        n2 += to_string(a);
        
        return n1<n2;
    }
};

33. 醜數

在這裏插入圖片描述

暴力法

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        
        if(index == 0)        //不加這個報錯!
            return 0;
        
        if(index == 1)
            return 1;
        
        v = vector<int>(index, 0x3f3f3f3f);
        v[0] = 1;
        
        for(int i=1; i<index; i++)        //計算第 i+1 個醜數
            for(int j=0; j<i; j++)        //分別選取前 i 個醜數乘2、3、5,所得結果最小作爲對應值
            {
                if(v[i-1] < v[j]*2)
                    v[i] = min(v[i], v[j]*2);
                if(v[i-1] < v[j]*3)
                    v[i] = min(v[i], v[j]*3);
                if(v[i-1] < v[j]*5)
                    v[i] = min(v[i], v[j]*5);
            }
        
        return v[index-1];
    }
    
private:
    vector<int> v;
};

優化:

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        
        if(index == 0)        //不加這個報錯!
            return 0;
        
        if(index == 1)
            return 1;
        
        v = vector<int>(index, 0x3f3f3f3f);
        v[0] = 1;
        
        int pos2 = 0;
        int pos3 = 0;
        int pos5 = 0;
        for(int i=1; i<index; i++)        //計算第 i+1 個醜數
        {
            v[i] = min(v[pos2]*2, min(v[pos3]*3, v[pos5]*5));
            if(v[i] == v[pos2]*2)
                pos2++;
            if(v[i] == v[pos3]*3)
                pos3++;
            if(v[i] == v[pos5]*5)
                pos5++;
        }
        
        return v[index-1];
    }
    
private:
    vector<int> v;
};

34. 第一個只出現一次的字符位置

在這裏插入圖片描述

class Solution {
public:
    int FirstNotRepeatingChar(string str) {
        
        for(int i=0; i<str.length(); i++)
        {
            m[str[i]]++;
        }
        
        for(int i=0; i<str.length(); i++)
            if(m[str[i]] == 1)
               return i;
        return -1;
    }
 
private:
    map<char, int> m;
};

35. 兩個鏈表的第一個公共結點

在這裏插入圖片描述

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {\
        
        set<ListNode *> s;
                                                                        
        for (auto it = pHead1; it != nullptr; it = it->next)
            s.insert(it);
        
        for (auto it = pHead2; it != nullptr; it = it->next)
            if (s.find(it) != s.end())
                return it;
                                                                        
        return nullptr;
    }
};

數組長度

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
    ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {\
        
        ListNode *p1 = pHead1;
        int len1 = 0;                                                                
        ListNode *p2 = pHead2;
        int len2 = 0;                                                                
        
        while(p1)
        {
            p1 = p1->next;
            len1++;
        }
        while(p2)
        {
            p2 = p2->next;
            len2++;
        }
                                                                        
        p1 = pHead1;
        p2 = pHead2;
        if(len1 > len2)
        {
            int dis = len1-len2;
            while(dis-->0)
                p1 = p1->next;
        }else{
            int dis = len2-len1;
            while(dis-->0)
                p2 = p2->next;
        }
        
        while(p1 && p2)
        {
            if(p1 == p2)
                return p1;
            p1 = p1->next;
            p2 = p2->next;
        }
                                                                        
        return nullptr;
    }
};

36. 數字在排序數組中出現的次數

在這裏插入圖片描述

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        
        int ret = 0;
        int l = 0;
        int r = data.size()-1;
        
        while(l <= r)
        {
            int mid = l+(r-l)/2;
            if(data[mid] == k)
            {
                int pre = mid-1;
                while(pre>=0 && data[pre]==k)
                {
                    ret++;
                    pre--;
                }
                
                int post = mid+1;
                while(post<data.size() && data[post]==k)
                {
                    ret++;
                    post++;
                }
                
                return ret+1;
            }else if(data[mid] > k){
                r = mid-1;
            }else{
                l = mid+1;
            }
        }
        
        return 0;
    }
};

37. 二叉樹的深度

在這裏插入圖片描述

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    int TreeDepth(TreeNode* pRoot)
    {
        int ret = 0;
        if(!pRoot)
            return ret;
        
        inOrder(pRoot, 1, ret);
        return ret;
    }
    
private:
    void inOrder(TreeNode *node, int level, int &ret)
    {
        if(!node)
            return ;
        
        if(node->left)
            inOrder(node->left, level+1, ret);
        
        ret = max(ret, level);
        
        if(node->right)
            inOrder(node->right, level+1, ret);
    }
};

精簡版

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/

class Solution {
public:
    int TreeDepth(TreeNode *pRoot) {
        if (pRoot == nullptr)
            return 0;
        return max(TreeDepth(pRoot->left), TreeDepth(pRoot->right)) + 1;
    }
};

38. 平衡二叉樹

在這裏插入圖片描述

class Solution {
public:
    bool IsBalanced_Solution(TreeNode* pRoot) {

        if(!pRoot)
            return true;
        
        return preorder(pRoot);
    }
    
 private:
    int treeDepth(TreeNode *node)
    {
        if(!node)
            return 0;
        return max(treeDepth(node->left), treeDepth(node->right))+1;
    }
    
    bool preorder(TreeNode *node)
    {
        if(!node)
            return true;
        
        int lDepth = treeDepth(node->left);
        int rDepth = treeDepth(node->right);
        return abs(lDepth-rDepth)<=1&&preorder(node->left)&&preorder(node->right);
    }
};

39. 數組中只出現一次的數字

在這裏插入圖片描述

  1. 數組異或
  2. 找出結果中的最低一位爲1
  3. 按照這一位是否爲1把數組分爲兩組
  4. 每組分別各自異或
class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {

        if(data.size() < 2)
            return ;
        
        int tmp = data[0];
        for(int i=1; i<data.size(); i++)
            tmp ^= data[i];
        
        //找到最低位爲1
        int index = 0;
        while((tmp&1) == 0)
        {
            tmp = tmp >> 1;
            index++;
        }
            
        int n1 = 0;
        int n2 = 0;
        for(int i=0; i<data.size(); i++)
        {
            //判斷第 index 位是否爲 1
            if(isBit(data[i], index))
                n1 ^= data[i];
            else
                n2 ^= data[i];
        }
        
        *num1 = n1;
        *num2 = n2;
    }
    
private:
    bool isBit(int num, int index)
    {
        if(num>>index & 1 != 0)
            return true;
        return false;
    }
};

40. 和爲S的連續正數序列

在這裏插入圖片描述

雙指針

class Solution {
public:
    vector<vector<int> > FindContinuousSequence(int sum) {
        
        vector<vector<int>> ret;
        if(sum < 3)
            return ret;
        
        int l = 1;
        int r = 2;
        
        
        while(l < r)
        {
            int n = (l+r)*(r-l+1)/2;        //求出 [l...r] 的和
            if(n == sum)
            {
                vector<int> v;
                for(int i=l; i<=r; i++)
                    v.push_back(i);
                ret.push_back(v);
                
                l++;
            }else if(n < sum){
                r++;
            }else
                l++;
        }
        
        return ret;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章