【Leetcode系列之一】Leetcode OJ 10道入门题研究

1.Single Number

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?


Solution:

public class Solution {
	public  static int singleNumber(int[] A) {
		int single = 0;
		for (int i : A)
			single ^= i;
		return single;

	}
}

该函数通过异或(xor)来消去出现两次的值,最终保留单个值。异或满足交换律和结合律,因此相同的值可以抵消最终保留单个值。

2.Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

Solution:http://oj.leetcode.com/discuss/2729/time-limited-when-i-change-to-simplified-code

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode *root) {
        return root ? 1 + max(maxDepth(root->left), maxDepth(root->right)) : 0;
    }
};


分析:

若该树为null,返回0。否则递归求解。对每一个节点,取左子树和右子树的最大值并+1,直至求至叶子节点时为null返回0。



3.Same Tree

Given two binary trees, write a function to check if they are equal or not.

Two binary trees are considered equal if they are structurally identical and the nodes have the same value.

Solution: https://oj.leetcode.com/discuss/3470/seeking-for-better-solution

/**
 * Definition for binary tree
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSameTree(TreeNode *p, TreeNode *q) {
        return ((!p && !q) || ( p && q && p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p->right, q->right)));
    }
};

Analysis:     !p and !q will get evaluated first. Because of the || comparison, if !p && !q returns true, then the rest of the return won't even get executed, so there's no worries about trying to de-reference a null pointer. Then we have to ensure that neither pointer is null with p && q. If either of those fail, we know the tree is inequal because e have already proved that both pointers are not null. At this point we know that both pointers are valid and can de-reference them. If their values are equal, then make proceed to the next iteration.



4.Unique Binary Search Trees

Given n, how many structurally unique BST's (binary search trees) that store values 1...n?

For example,
Given n = 3, there are a total of 5 unique BST's.

   1         3     3      2      1
    \       /     /      / \      \
     3     2     1      1   3      2
    /     /       \                 \
   2     1         2                 3
Solution: http://oj.leetcode.com/discuss/620/attention-adding-lines-help-reducing-running-time-from-1140ms
class Solution {
    public:
        /**
     * Solution:
     * DP
     * a BST can be destruct to root, left subtree and right subtree.
     * if the root is fixed, every combination of unique left/right subtrees forms
     * a unique BST.
     * Let a[n] = number of unique BST's given values 1..n, then
     * a[n] = a[0] * a[n-1]     // put 1 at root, 2...n right
     *      + a[1] * a[n-2]     // put 2 at root, 1 left, 3...n right
     *      + ...
     *      + a[n-1] * a[0]     // put n at root, 1...n-1 left
     */
    int numTrees(int n) {
        if (n < 0) return 0;
        vector<int> trees(n+1, 0);
        trees[0] = 1;
    
        for(int i = 1; i <= n; i++) 
            for (int j = 0; j < i; j++) 
                trees[i] += trees[j] * trees[i-j-1];
    
        return trees[n];
    }
};
分析:本题对于第n个BST,若1位于root,则剩下的n-1位于1的右子树,此时总数为a[0]*a[n-1];若2位于root,则1位于左子树,3,4,...,n等n-2个数位于右子树,此时总数为a[1]*a[n-2],依次类推,有:
a[n]  = a[0] * a[n-1]     // put 1 at root, 2...n right
         + a[1] * a[n-2]     // put 2 at root, 1 left, 3...n right
         + ...
         + a[n-1] * a[0]
使用DP(动态规划)来求解本题。

5.Linked List Cycle

Given a linked list, determine if it has a cycle in it.

Follow up:
Can you solve it without using extra space?

Solution:
首先,遍历链表,并对节点作标记,若有重复则表示为一环,这种方法的时间复杂度为O(n)。
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode *curNode = head;
        int flags = 2147483648;
        while(curNode != 0){
            if(curNode->val==flags)
                return 1;
            curNode->val = flags;
            curNode = curNode->next;
        }
        return 0;
    }
};
https://oj.leetcode.com/discuss/122/does-everyone-solved-it-with-o-n-complexity中有faster runner 和slowrunner 的思路,fasterrunner每次前进两步,slowrunner每次前进一步,如果两者会重合证明链表有环
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode *slow = head;
        ListNode *fast = head;
        while(fast != 0 && fast->next != 0)
        {
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast)
                return true;
        }
        return false;
    }
};


6.Binary Tree Inorder Traverse

Given a binary tree, return the inorder traversal of its nodes' values.

For example:
Given binary tree {1,#,2,3},

   1
    \
     2
    /
   3

return [1,3,2].

Note: Recursive solution is trivial, could you do it iteratively?

confused what "{1,#,2,3}" means? > read more on how binary tree is serialized on OJ.

Solution: recursive solution

class Solution {
public:
    vector<int> res = {};
    vector<int> inorderTraversal(TreeNode *root) {
        if (root == NULL) {
            return res;
        }
        inorderTraversal(root->left);
        res.push_back(root->val);
        inorderTraversal(root->right);
        return res;
    }
};

7.Population Next Right Pointers in Each Node

Given a binary tree

    struct TreeLinkNode {
      TreeLinkNode *left;
      TreeLinkNode *right;
      TreeLinkNode *next;
    }

Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL.

Initially, all next pointers are set to NULL.

Note:

  • You may only use constant extra space.
  • You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children).

For example,
Given the following perfect binary tree,

         1
       /  \
      2    3
     / \  / \
    4  5  6  7

After calling your function, the tree should look like:

         1 -> NULL
       /  \
      2 -> 3 -> NULL
     / \  / \
    4->5->6->7 -> NULL
Solution: recursive solution

/**
 * Definition for binary tree with next pointer.
 * struct TreeLinkNode {
 *  int val;
 *  TreeLinkNode *left, *right, *next;
 *  TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
 * };
 */
class Solution {
public:
    void connect(TreeLinkNode *root) {
        if(root==NULL) return;

        if(root->left)
            root->left->next = root->right;
        if(root->right)
            root->right->next = (root->next) ? root->next->left:NULL;
        connect(root->left);
        connect(root->right);
    }
};


8.Search Insert Position

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume no duplicates in the array.

Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0

Solution:
class Solution {
public:
    int searchInsert(int A[], int n, int target) { 
        for(int i=0;i<n;i++){
            if(A[i]==target){
                return i;
            }
            if(A[i]>target){
                return i;
            }
        }
        return n;
    }
};


9.Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once.

For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.

Soltuion:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *deleteDuplicates(ListNode *head) {
        ListNode *curr = head;
        while(curr != NULL && curr->next !=NULL){
            if(curr->val == curr->next->val){
                curr->next = curr->next->next;
            }
            else
                curr = curr->next;
        }
        return head;
    }
};

10.Roman to Integer

Given a roman numeral, convert it to an integer.

Input is guaranteed to be within the range from 1 to 3999.

Roman numeral :  http://en.wikipedia.org/wiki/Roman_numerals

class Solution {
public:
    int romanToInt(string s) {
        int res = 0;
        for (int i = s.size() - 1; i >= 0; i--)
        {
            switch (s[i])
            {
            case 'I':
                res += (res >= 5 ? -1 : 1);
                break;
            case 'V':
                res += 5;
                break;
            case 'X':
                res += 10 * (res >= 50 ? -1 : 1);
                break;
            case 'L':
                res += 50;
                break;
            case 'C':
                res += 100 * (res >= 500 ? -1 : 1);
                break;
            case 'D':
                res += 500;
                break;
            case 'M':
                res += 1000;
                break;
            }
        }
        return res;
    }
};

分析:该题初看无从下手,后来找到   makeittrue的解法,清晰简洁,推荐!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值