###不给自己任何借口
今日题目:
1、加油站 ; tag:贪心
2、删除有序链表的重复元素II tag:链表
今日摘录:
如果你非要拒绝我,请不要那么绝对。因为你的一句“我没有那么喜欢你”,我都可以解读为“我有一点喜欢你。
——沈煜伦
134. Gas Station | Difficulty: Medium
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.
tag:贪心
题意:在一个环路上有N个加油站,每一个加油站都有gas[i]的油,并且去下一个加油站都需要话费cost[i],如果能走通就返回出发点的坐标,如果不能就返回-1.
思路:
1、这道题还好,不算难,理清楚思路就很简单了。因为有N个加油站和N条路,所以可以将每一个加油站和每一条路都一一对应起来,第一步判断总油量是否大于总耗油,如果这个不能满足说明一定是到不了的。然后逐个位置去判断,思路有点类似最长子序列和,大概就是如果当前点出发去下一个点剩下的油量如果小于0(即在半路会没油),当前点就不可能是出发点,就将总油量置0,继续找出发点。如果到达点油量大于0,说明这段路可以走,这个时候将目前油量更新为到达点油量。如果出发前油量是0,那么这个点就是出发点。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
vector<int>res(gas.size(),0);
int index = -1;
int sum = 0;
for(int i=0;i<gas.size();i++)
{
res[i] = gas[i]-cost[i];
sum+=res[i];
}
if(sum<0) return -1;
sum=0;
for(int i=0;i<res.size();i++)
{
int reach = sum+res[i];
if(reach<0)
sum=0;
else if (sum==0)
{
sum = reach;
index = i;
}
else
{
sum = reach;
}
}
return index;
}
};
结果:8ms
2、思路一样,看了下https://discuss.leetcode.com/topic/1344/share-some-of-my-ideas/2的解法,明显聪明很多,学习了
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int start=0,tank = 0,total=0;
for(int i=0;i<gas.size();i++)
{
if((tank = tank+gas[i]-cost[i])<0)
{
start = i+1;
total +=tank;
tank = 0;
}
}
return (total+tank<0)?-1:start;
}
};
结果:8ms
82. Remove Duplicates from Sorted List II | Difficulty: Medium
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.
相关题目:Remove Duplicates from Sorted List
tag:链表
题意:将一个有序链表中的所有重复元素删除(Remove Duplicates from Sorted List是所有重复元素保留一个)
思路:
第一步找到整个链表的头
第二步循环去判断链表中间的元素是否存在重复的,利用一个prev来保存之前尚未存在存在的子链表的尾部,flag来判断是否出现过重复的元素
第三步判断链表的尾部是否重复元素
/**
* 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) {
if(!head || !head->next) return head;
bool flag = false;
//找到头在什么位置
while(head)
{
if(head->next && head->next->val==head->val)
{head = head->next;flag = true;}
else
{
if(flag) {head = head->next;flag = false;}
else break;
}
}
ListNode*pNode = head;
ListNode*prev = NULL;
flag = false;
//遍历节点
while(pNode)
{
//如果有下一个并且下一个节点不等于当前节点
if(pNode->next&& pNode->next->val != pNode->val)
{
//这里找到的是值有变化的位置,这里又有两种情况,第一种情况是没有出现连续重复值,直接prev和pNode都往后就行了
if(!flag)
{
prev = pNode;
pNode = pNode->next;
}
//第二种情况是之前出现过连续重复值值,需要把这些连续值都删除,并将flag还原成false
else
{
prev->next = pNode->next;
pNode = pNode->next;
flag = false;
}
}
//下一个节点等于当前节点
else
{
//这里都是值不变的可能性,又分了两种情况
//第一种情况还没到底,置flag为true,继续往后访问
if(pNode->next)
{
pNode = pNode->next;
flag = true;
}
//第二种情况是到底了,如果出现了连续重复值,之前将最后一个非重复节点当成最后节点
else
{
if(flag) prev->next = NULL;
pNode = pNode->next;
}
}
}
return head;
}
};
结果:12ms
2、递归版本,把逻辑理清代码很简单
/**
* 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) {
if(!head) return NULL;
if(!head->next) return head;
int val = head->val;
ListNode*p = head->next;
if(head->next->val != val)
{
head->next = deleteDuplicates(head->next);
return head;
}
else
{
while(p && p->val == val) p = p->next;
return deleteDuplicates(p);
}
}
};
结果:8ms
update:2016.9.16
第二次刷代码
/**
* 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) {
if(!head || !head->next) return head;
int val;
ListNode*newHead = head;
while(newHead->next)
{
if(newHead->next->val == newHead->val)
{
int val = newHead->val;
while(newHead && newHead->val ==val) newHead = newHead->next;
if(!newHead) return newHead;
}
else
break;
}
ListNode *pre = newHead,*cur = newHead;
while(cur)
{
if(cur->next )
{
if(cur->val!=cur->next->val)
{
pre = cur;
cur = cur->next;
}
else
{
val = cur->val;
while(cur && cur->val==val) cur = cur->next;
pre->next = cur;
}
}
else
{
if(cur->val==val) pre->next=NULL;
cur = cur->next;
}
}
return newHead;
}
};
结果:9ms