LeetCode(Medium)

目录:

  1. Linked List Cycle

  2. Binary Tree Right Side View

  3. Add Two Numbers

  4. Word Break

  5. Two Sum

  6. 3Sum

  7. Gas Station

  8. Linked List Cycle II


 

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?

思路:两个指针,一个指向头结点,另一个指向头结点的下一个结点,然后第一个指针每次前进一步,第二个指针每次前进两步,如果两个指针能够相遇,则存在环。

 

复制代码
 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     bool hasCycle(ListNode *head) 
12     {
13         if(head == NULL || head->next == NULL) 
14             return false;
15         ListNode *p = head->next;
16         while(p != NULL && p->next != NULL && p != head)
17         {
18             head = head->next;
19             p = p->next->next;
20         }
21         if(p == head)
22             return true;
23         else
24             return false;
25     }
26 };
复制代码

Binary Tree Right Side View  返回目录

Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom.

For example:
Given the following binary tree,

   1            <---
 /   \
2     3         <---
 \     \
  5     4       <---

 

You should return [1, 3, 4].

 思路:分别遍历根结点的左子树和右子树的右边,然后将右子树的右孩子,以及左子树的孩子中所在层数大于右子最后一个孩子所在层数的孩子保存起来即可!

复制代码
 1 /**
 2  * Definition for binary tree
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<int> rightSideView(TreeNode *root) 
13     {
14         vector<int> ret;
15         if(root == NULL) 
16             return ret;
17         ret.push_back(root->val);
18         vector<int> retl;
19         vector<int> retr;
20         retl = rightSideView(root->left);
21         retr = rightSideView(root->right);
22         for(int i = 0; i < retr.size(); ++i)
23                 ret.push_back(retr[i]);
24         if(retr.size() < retl.size())
25         {
26             for(int i = retr.size(); i < retl.size(); ++i)
27                 ret.push_back(retl[i]);
28         }
29         return ret;
30     }
31 };
复制代码

 


Add Two Numbers  返回目录

You are given two linked lists representing two non-negative numbers. 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.

Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8

思路:和经典的大数乘法思路一样!

复制代码
 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) 
12     {
13         if(l1 == NULL && l2 == NULL) return NULL;
14         if(l1 == NULL) return l2;
15         if(l2 == NULL) return l1;
16         ListNode* result = new ListNode(0);
17         ListNode* head = result;
18         int carry = 0;
19         while(l1 != NULL || l2 != NULL)
20         {
21             int tmp;
22             if(l1 != NULL && l2 != NULL)
23             {
24                 tmp = l1->val + l2->val;
25                 l1 = l1->next;
26                 l2 = l2->next;
27             }
28             else if(l1 != NULL && l2 == NULL)
29             {
30                 tmp = l1->val;
31                 l1 = l1->next;
32             }
33             else
34             {
35                 tmp = l2->val;
36                 l2 = l2->next;
37             }
38             head->next = new ListNode((carry + tmp) % 10);
39             head = head->next;
40             carry = (carry + tmp) / 10;
41         }
42         if(carry > 0)
43         {
44             head->next = new ListNode(carry);
45         }
46         return result->next;
47     }
48 };
复制代码

 


 

Word Break 返回目录

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".

思路:对于s,分解成从第0个元素到第1,2, 3, ..., index,...的子串,用 bool f[s.size()] 数组作为标志数组,如果 0 到 index 所对应的子串在 dict 中,则f[index] = true,否则为 false.

复制代码
 1 class Solution {
 2 public:
 3     bool wordBreak(string s, unordered_set<string>& wordDict) 
 4     {
 5         int size = s.size();
 6         if (0 == size)  return true;
 7         if (0 == wordDict.size())   return false;
 8 
 9         //f[i]表示前[0, i]字符是否匹配
10         bool* f = new bool[size];
11         for (int i = 0; i < size; ++i)
12             f[i] = false;
13     
14         for (int i = 0; i < size; ++i)
15         {
16             for (int j = i; j >= 0; --j)
17             {
18                 if (0 == j || f[j - 1])
19                 {
20                     if (wordDict.find(s.substr(j, i - j + 1)) != wordDict.end())
21                     {
22                         f[i] = true;
23                         break;
24                     }
25                 }
26             }
27         }
28     
29         bool re = f[size - 1];
30     
31         delete[] f;
32     
33         return re;            
34     }
35 };
复制代码

 

程序是从一位网友那里复制过来的,有一点难懂,下面结合题中所述,走一遍程序:

  • i == 0, j == 0;  满足条件 j == 0调用find(),s.substr(j, i - j + 1) == "l",找不到,f[0]依旧为 false, --j, j < 0内层for终止  
  • i == 1, j == 1,if语句的条件不满足,j--, j == 0, 满足if 的 j == 0,调用find(), s.substr(j, i - j + 1) == "le",找不到,f[1]依旧为 false, --j, j < 0内层for终止,同理f[2]也依旧是false
  • i == 3, j == 3, 因为 j != 0,且f[j - 1] == false, if 语句的条件不满足, 于是  j 递减,知道 j == 0 时,if 判读为真,执行 find(),  s.substr(j, i - j + 1) == "leet",在 dict 中找到,f[3] = true
  • i == 4, j == 4, 因为 f[3] == true, if 语句满足 --> find(), s.substr(j, i - j + 1) == s.substr(4, 1) == "", 找不到,f[4] = false, j递减,知道 j == 0时再次满足 if 条件,find(), s.substr(j, i - j + 1) == ‘leetc’,找不到,如此继续
  • 可以看出,要是满足题目要求,f[s.size() - 1]必然为true

 


 

Two Sum  返回目录

Given an array of integers, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2

复制代码
 1 class Solution {
 2 public:
 3     vector<int> twoSum(vector<int>& nums, int target) 
 4     {
 5         int i, sum;
 6         vector<int> results;
 7         map<int, int> hmap;
 8         for(i=0; i<nums.size(); i++)
 9         {
10             // 元素值作为key,元素位置作为value
11             if(!hmap.count(nums[i]))
12             {
13                 hmap.insert(pair<int, int>(nums[i], i));
14             }
15             if(hmap.count(target-nums[i]))
16             {
17                 int n=hmap[target-nums[i]];
18                 // 这里需要判断一下,否则对于
19                 // 输入:[1,2,3], 2
20                 // 会出现输出:[1, 1]
21                 if(n != i)
22                 {
23                     results.push_back(n+1);
24                     results.push_back(i+1);
25                     return results;
26                 }
27 
28             }
29         }
30         return results;
31     }
32 };
复制代码

3Sum  返回目录

Given an array S of n integers, are there elements abc in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

  • Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
  • The solution set must not contain duplicate triplets.

 

    For example, given array S = {-1 0 1 2 -1 -4},

    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)
复制代码
 1 class Solution {
 2 public:
 3     vector<vector<int> > threeSum(vector<int> &num) 
 4     {   
 5         int n = num.size();
 6         sort(num.begin(), num.end());
 7         vector<vector<int> > res;
 8         for(int i = 0; i < n-2; i++) // 注意这里是n-2
 9         {
10             if(i > 0 && num[i] == num[i-1])continue;//重复的元素不用计算
11             int target2 = 0 - num[i];
12             twoSum(num, i+1, target2, res);
13         }
14         return res;
15     }
16 
17     void twoSum(vector<int> &sortedNum, int start, int target, vector<vector<int> >&res)
18     {
19         int head = start, tail = sortedNum.size() - 1;
20         while(head < tail)
21         {
22             int tmp = sortedNum[head] + sortedNum[tail];
23             if(tmp < target)
24                 head++;
25             else if(tmp > target)
26                 tail--;
27             else
28             { 
29                 res.push_back(vector<int>{sortedNum[start-1], sortedNum[head], sortedNum[tail]});
30                 
31                 //为了防止出现重复的二元组,跳过重复元素
32                 int k = head+1;
33                 while(k < tail && sortedNum[k] == sortedNum[head])k++;
34                 head = k;
35                 
36                 k = tail-1;
37                 while(k > head && sortedNum[k] == sortedNum[tail])k--;
38                 tail = k;
39             }
40         }
41     }
42 };
复制代码

Gas Station  返回目录

There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station's index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.

复制代码
 1 class Solution {
 2 public:
 3     int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
 4         int n = gas.size();
 5         vector<int> v(n);
 6         for (int i = 0; i < n; i++) v[i] = gas[i] - cost[i];
 7         int start = 0, end = 0, gasInTank = 0;
 8         while (start < n) 
 9         {
10             while (gasInTank >= 0 && end < start + n) gasInTank += v[(end++) % n];
11             //如果剩余汽大于于0,并且遍历了n个加油站
12             if (gasInTank >= 0 && end == start + n) return start;
13             
14             gasInTank -= v[start++];
15         }
16         return -1;
17     }
18 };
复制代码

 Linked List Cycle II 返回目录

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

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

 解析:http://blog.csdn.net/sysucph/article/details/15378043

复制代码
 1 /**
 2  * Definition for singly-linked list.
 3  * struct ListNode {
 4  *     int val;
 5  *     ListNode *next;
 6  *     ListNode(int x) : val(x), next(NULL) {}
 7  * };
 8  */
 9 class Solution {
10 public:
11     ListNode *detectCycle(ListNode *head) 
12     {
13         if(head == NULL)
14             return NULL;
15         ListNode *ptr1 = head;
16         ListNode *ptr2 = head;
17         
18         while(ptr2->next != NULL && ptr2->next->next != NULL)
19         {
20             ptr1 = ptr1->next;
21             ptr2 = ptr2->next->next;
22             if(ptr1 == ptr2)
23             {
24                 ptr1 = head;
25                 while(ptr1 != ptr2)
26                 {
27                     ptr1 = ptr1->next;
28                     ptr2 = ptr2->next;
29                 }
30                 return ptr1;
31             }
32             
33         }
34         return NULL;
35     }
36 };
复制代码

 

 

  

posted @   90Zeng  阅读(503)  评论(0)    收藏  举报
编辑推荐:
· 编码之道,道心破碎。
· 记一次 .NET 某发证机系统 崩溃分析
· 微服务架构学习与思考:SOA架构与微服务架构对比分析
· tomcat为什么假死了
· 聊一聊 Linux 上对函数进行 hook 的两种方式
阅读排行:
· 编码之道,道心破碎。
· 知名开源项目Alist被收购!惹程序员众怒,开团炮轰甲方
· 如何给 GitHub Copilot "洗脑”,让 AI 精准遵循指令产出高质量代码
· 历时半年,我将一个大型asp.net的零代码快速开发平台转成了java
· 突发,小红书开发者后门被破解?!
点击右上角即可分享
微信分享提示