LeetCode

1. Two Sum

题目描述

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.

输入输出样例

Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

解题思路

  • 遍历数组,用map存value-index;
  • 存的时候顺便判断一下互补元素是否存在key中,如果存在,万事大吉,输出即可;不存在,把当前元素存进map中;
  • 先判断,再存,这样可以避免重复元素引起的问题。

AC的代码

class Solution {
public:
	vector<int> twoSum(vector<int>& nums, int target) {
		map<int, int> v2i;
		vector<int> ret;
		for (size_t i = 0; i < nums.size(); i++)
		{	
			if (v2i.find(target-nums[i]) != v2i.end())
			{				
				ret.push_back(v2i[target - nums[i]]);
				ret.push_back(i);
				return ret;
			}			
			v2i[nums[i]] = i;
		}
	}
};

2. Add Two Numbers

题目描述

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.

输入输出样例

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.

解题思路

  • 同时遍历两个链表,逐个元素相加,注意考虑进位的问题,当前用完的进位要清零(hold);
  • 结果的链表每次新添元素的时候,直接为在当前元素的next new一个node,然后把指针移动到next,这样可以省去prev的指针;
  • 为了支持上述操作,sum初始是一个值为0的节点,只需要在遍历的时候进行一次是否为首次赋值的判断;
  • 遍历完成后检查一下最后一次进位是否有值,如果有的话就创建一个新的节点。

AC的代码

class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* sum = new ListNode(0);
		ListNode* cur_sum = sum;		
		int hold = 0;
		bool first_flag = true;
		while (l1!= NULL || l2 != NULL)
		{
			int d1 = 0, d2 = 0;
			if (l1 != NULL)
			{
				d1 = l1->val;
				l1 = l1->next;
			}
			if (l2 != NULL)
			{
				d2 = l2->val;
				l2 = l2->next;
			}
			int cur_digit = d1 + d2 + hold;
			hold = 0;
			if (cur_digit > 9)
			{
				hold = 1;
				cur_digit -= 10;
			}

			if (first_flag)
			{
				cur_sum->val = cur_digit;
				first_flag = false;
			}
			else
			{
				cur_sum->next = new ListNode(cur_digit);				
				cur_sum = cur_sum->next;
			}			
		}
		if (hold == 1)
		{
			cur_sum->next = new ListNode(1);			
		}
		return sum;
    }
};

3. Longest Substring Without Repeating Characters

题目描述

Given a string, find the length of the longest substring without repeating characters.

输入输出样例

Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

解题思路

  • sliding window的概念,维护一个首尾指针,记录当前不重复子串的首尾
  • 存储方式,用map来存字符到index,尾指针向后移动的时候,如果发现前面有重复的字符,就把头指针指向重复的字符位置
  • 维护一个max长度变量,记录当前最长的长度
  • 只需要遍历一次字符串,O(n)复杂度

AC代码

int lengthOfLongestSubstring(string s) {
		int n = s.length();
		int max_len = 0;
		int i = 0, j = 0;
		map<char,int> c2i;
		while (j < n)
		{
			if (c2i.find(s[j]) != c2i.end()) // insert, move tail
				i = i < c2i[s[j]] ? c2i[s[j]] : i;
			
			c2i[s[j]] = j+1;			
			max_len = max_len < (j - i + 1) ? j - i + 1 : max_len;
			j++;
		}
		return max_len;
	}
};

94. Binary Tree Inorder Traversal

二叉树中序遍历

解题思路-递归

  • 先遍历左节点,输出父节点,再遍历右节点
vector<int> inorderTraversal(TreeNode* root) {
        
        vector<int> values;
        traverse(root, values);
        return values;
    }
    void traverse(TreeNode* node, vector<int> &values)
    {        
        if (node)
        {
            traverse(node->left, values);
            values.push_back(node->val);
            traverse(node->right, values);
        }        
    }

解题思路-循环

  • 深度优先,用stack存,先遍历左节点到底,然后pop时记录当前的value,再将遍历起点变成右子树
vector<int> inorderTraversal(TreeNode* root) {
        vector<int> values;
        stack<TreeNode*> nodes;        
        TreeNode* cur = root;
        while (cur || !nodes.empty())
        {
            while (cur)
            {
                nodes.push(cur);
                cur = cur->left;
            }            
            cur = nodes.top();
            nodes.pop();
            values.push_back(cur->val);
            cur = cur->right;
        }        
        return values;        
    }

104. Maximum Depth of Binary Tree

找到一个二叉树的最大深度

递归代码

不断计算左右子树的深度

int maxDepth(TreeNode* root) 
    {
        return findDepth(root, 0);
    }
    
    int findDepth(TreeNode* root, int depth)
    {
        if (root == NULL)
            return depth;
        depth++;
        auto left_depth = findDepth(root->left, depth);
        auto right_depth = findDepth(root->right, depth);
        depth = left_depth > right_depth? left_depth: right_depth;
        return depth;
    }

广度优先遍历

记得要遍历queue的时候要提取记录下来queue的大小,不要用queue.size(),因为过程中它的size会不断发生变化。

int maxDepth(TreeNode* root) {
        queue<TreeNode*> nodes;
        if (root)
            nodes.push(root);
        int depth = 0;
       
        while (nodes.size() > 0)
        {            
            depth++;
            int n = nodes.size();
            for (int i = 0;i < n; i++)
            {
                auto cur = nodes.front();
                nodes.pop();
                if (cur->left) nodes.push(cur->left);
                if (cur->right) nodes.push(cur->right);
            }
        }
        return depth;  
    }

136. Single Number

一个数组里,除了一个单身数,其他都是成对的,找到那只单身数 ==|||

解题思路

按位异或,^

AC代码

int singleNumber(int A[], int n) {
        int single = A[0];
        for (int i = 1;i < n;i++)
        {
            single = single^A[i];
        }
        return single;
    }

169. Majority Element

返回一个数组中的众数。

解题思路

  • HashMap 用map存每个数值对应的频数,最后从map中取出频数最大的key,思路比较直接。
  • 用一个变量来存取当前位置之前的众数,很巧妙,代码如下。

AC代码

int majorityElement(vector<int>& nums) 
{
        int me = 0;
        int cur_max_count = 0;
        for (int i = 0;i < nums.size(); i++)
        {
            if (cur_max_count == 0) // new start
                me = nums[i];
            cur_max_count += (me == nums[i]) ? 1 : -1;
        }
        return me;
}

171. Excel Sheet Column Number

把Excel表格的列标号,转换为数字。如“A”对应1,“B”对应2,“AB”对应28,以此类推。

解题思路

转换成26进制。

AC代码

   int titleToNumber(string s) {
        int n = s.length();
        int sum = 0;
        for (int i = n -1; i >= 0; i--)
        {
            sum += (s[i] - 'A' + 1) * pow(26,n-1-i);
        }
        return sum;        
    }

283. Move Zeroes

把非零元素都移到数组前面,且保证相对次序不变。

解题思路

  • 用一个指针遍历数组,用另一个指针lastNonZeroPos用于标记数组从前往后最后一个能够摆放非零元素的位置
  • 当前数值非零时,和lastNonZeroPos位置的元素进行交换

AC代码

void moveZeroes(vector<int>& nums) {
        int n = nums.size();
        int lastNonZeroPos = 0;
        for (int i = 0; i < n; i++)
        {
           if (nums[i] != 0)
               swap(nums[i],nums[lastNonZeroPos++]);
        }        
    }
posted @ 2018-07-13 15:04  zhsuiy  阅读(263)  评论(0编辑  收藏  举报