mirror of
https://github.com/chefyuan/algorithm-base.git
synced 2024-12-27 21:06:17 +00:00
Merge branch 'main' of https://github.com/chefyuan/algorithm-base
This commit is contained in:
commit
f765951ec7
@ -33,6 +33,8 @@
|
||||
|
||||
我们首先将链表的所有元素都保存在数组中,然后再利用双指针遍历数组,进而来判断是否为回文。这个方法很容易理解,而且代码实现也比较简单。
|
||||
|
||||
**题目代码**
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public boolean isPalindrome(ListNode head) {
|
||||
@ -72,6 +74,10 @@ class Solution {
|
||||
|
||||
![翻转链表部分](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/翻转链表部分.1v2ncl72ligw.gif)
|
||||
|
||||
#### **题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public boolean isPalindrome(ListNode head) {
|
||||
@ -129,3 +135,63 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
bool isPalindrome(ListNode* head) {
|
||||
if (head == nullptr || head->next == nullptr) {
|
||||
return true;
|
||||
}
|
||||
//找到中间节点,也就是翻转的头节点,这个在昨天的题目中讲到
|
||||
//但是今天和昨天有一些不一样的地方就是,如果有两个中间节点返回第一个,昨天的题目是第二个
|
||||
ListNode * midenode = searchmidnode(head);
|
||||
//原地翻转链表,需要两个辅助指针。这个也是面试题目,大家可以做一下
|
||||
//这里我们用的是midnode->next需要注意,因为我们找到的是中点,但是我们翻转的是后半部分
|
||||
|
||||
ListNode * backhalf = reverse(midenode->next);
|
||||
//遍历两部分链表,判断值是否相等
|
||||
ListNode * p1 = head;
|
||||
ListNode * p2 = backhalf;
|
||||
while (p2 != nullptr) {
|
||||
if (p1->val != p2->val) {
|
||||
return false;
|
||||
}
|
||||
p1 = p1->next;
|
||||
p2 = p2->next;
|
||||
}
|
||||
// 还原链表并返回结果,这一步是需要注意的,我们不可以破坏初始结构,我们只是判断是否为回文,
|
||||
//当然如果没有这一步也是可以AC,但是面试的时候题目要求可能会有这一条。
|
||||
midenode->next = reverse(backhalf);
|
||||
return true;
|
||||
}
|
||||
//找到中间的部分
|
||||
ListNode * searchmidnode (ListNode * head) {
|
||||
ListNode * fast = new ListNode(-1);
|
||||
ListNode * slow = new ListNode(-1);
|
||||
fast = head;
|
||||
slow = head;
|
||||
//找到中点
|
||||
while (fast->next != nullptr && fast->next->next != nullptr) {
|
||||
fast = fast->next->next;
|
||||
slow = slow->next;
|
||||
}
|
||||
return slow;
|
||||
}
|
||||
//翻转链表
|
||||
ListNode * reverse (ListNode * slow) {
|
||||
ListNode * low = nullptr;
|
||||
ListNode * temp = nullptr;
|
||||
//翻转链表
|
||||
while (slow != nullptr) {
|
||||
temp = slow->next;
|
||||
slow->next = low;
|
||||
low = slow;
|
||||
slow = temp;
|
||||
}
|
||||
return low;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -72,3 +72,24 @@ var hasCycle = function(head) {
|
||||
return false;
|
||||
};
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
bool hasCycle(ListNode *head) {
|
||||
ListNode * fast = head;
|
||||
ListNode * low = head;
|
||||
while (fast != nullptr && fast->next != nullptr) {
|
||||
fast = fast->next->next;
|
||||
low = low->next;
|
||||
if (fast == low) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -123,7 +123,9 @@ public class Solution {
|
||||
|
||||
![环形链表2](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/环形链表2.elwu1pw2lw0.gif)
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
public class Solution {
|
||||
@ -153,3 +155,34 @@ public class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode *detectCycle(ListNode *head) {
|
||||
//快慢指针
|
||||
ListNode * fast = head;
|
||||
ListNode * low = head;
|
||||
//设置循环条件
|
||||
while (fast != nullptr && fast->next != nullptr) {
|
||||
fast = fast->next->next;
|
||||
low = low->next;
|
||||
//相遇
|
||||
if (fast == low) {
|
||||
//设置一个新的指针,从头节点出发,慢指针速度为1,所以可以使用慢指针从相遇点出发
|
||||
ListNode * newnode = head;
|
||||
while (newnode != low) {
|
||||
low = low->next;
|
||||
newnode = newnode->next;
|
||||
}
|
||||
//在环入口相遇
|
||||
return low;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -82,6 +82,8 @@
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode insertionSortList(ListNode head) {
|
||||
@ -121,7 +123,45 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* insertionSortList(ListNode* head) {
|
||||
if (head == nullptr && head->next == nullptr) {
|
||||
return head;
|
||||
}
|
||||
//哑节点
|
||||
ListNode * dummyNode = new ListNode(-1);
|
||||
dummyNode->next = head;
|
||||
//pre负责指向新元素,last 负责指向新元素的前一元素
|
||||
//判断是否需要执行插入操作
|
||||
ListNode * pre = head->next;
|
||||
ListNode * last = head;
|
||||
ListNode * temphead = dummyNode;
|
||||
while (pre != nullptr) {
|
||||
//不需要插入到合适位置,则继续往下移动
|
||||
if (last->val <= pre->val) {
|
||||
pre = pre->next;
|
||||
last = last->next;
|
||||
continue;
|
||||
}
|
||||
//开始出发,查找新元素的合适位置
|
||||
temphead = dummyNode;
|
||||
while (temphead->next->val <= pre->val) {
|
||||
temphead = temphead->next;
|
||||
}
|
||||
//此时我们已经找到了合适位置,我们需要进行插入,大家可以画一画
|
||||
last->next = pre->next;
|
||||
pre->next = temphead->next;
|
||||
temphead->next = pre;
|
||||
pre = last->next;
|
||||
}
|
||||
return dummyNode->next;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -33,6 +33,10 @@ low = temp 即可。然后重复执行上诉操作直至最后,这样则完成
|
||||
|
||||
我会对每个关键点进行注释,大家可以参考动图理解。
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
```java
|
||||
class Solution {
|
||||
@ -81,8 +85,44 @@ var reverseList = function(head) {
|
||||
};
|
||||
```
|
||||
|
||||
C++代码
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* reverseList(ListNode* head) {
|
||||
//特殊情况
|
||||
if (head == nullptr || head->next == nullptr) {
|
||||
return head;
|
||||
}
|
||||
//反转
|
||||
return reverse(head);
|
||||
}
|
||||
ListNode * reverse (ListNode * head) {
|
||||
|
||||
ListNode * low = nullptr;
|
||||
ListNode * pro = head;
|
||||
while (pro != nullptr) {
|
||||
//代表橙色指针
|
||||
ListNode * temp = pro;
|
||||
//移动绿色指针
|
||||
pro = pro->next;
|
||||
//反转节点
|
||||
temp->next = low;
|
||||
//移动黄色指针
|
||||
low = temp;
|
||||
}
|
||||
return low;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
上面的迭代写法是不是搞懂啦,现在还有一种递归写法,不是特别容易理解,刚开始刷题的同学,可以只看迭代解法。
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
```java
|
||||
class Solution {
|
||||
@ -118,3 +158,26 @@ var reverseList = function(head) {
|
||||
};
|
||||
```
|
||||
|
||||
C++代码:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode * reverseList(ListNode * head) {
|
||||
//结束条件
|
||||
if (head == nullptr || head->next == nullptr) {
|
||||
return head;
|
||||
}
|
||||
//保存最后一个节点
|
||||
ListNode * pro = reverseList(head->next);
|
||||
//将节点进行反转。我们可以这样理解 4->next->next = 4;
|
||||
//4->next = 5;
|
||||
//则 5->next = 4 则实现了反转
|
||||
head->next->next = head;
|
||||
//防止循环
|
||||
head->next = nullptr;
|
||||
return pro;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -36,6 +36,8 @@
|
||||
|
||||
#### 题目代码
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode oddEvenList(ListNode head) {
|
||||
@ -60,3 +62,30 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* oddEvenList(ListNode* head) {
|
||||
if (head == nullptr || head->next == nullptr) {
|
||||
return head;
|
||||
}
|
||||
ListNode * odd = head;
|
||||
ListNode * even = head->next;
|
||||
ListNode * evenhead = even;
|
||||
|
||||
while (odd->next != nullptr && even->next != nullptr) {
|
||||
//将偶数位合在一起,奇数位合在一起
|
||||
odd->next = even->next;
|
||||
odd = odd->next;
|
||||
even->next = odd->next;
|
||||
even = even->next;
|
||||
}
|
||||
//链接
|
||||
odd->next = evenhead;
|
||||
return head;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -39,6 +39,10 @@
|
||||
|
||||
![删除重复节点2](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/删除重复节点2.3btmii5cgxa0.gif)
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode deleteDuplicates(ListNode head) {
|
||||
@ -68,3 +72,35 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* deleteDuplicates(ListNode* head) {
|
||||
if(head == nullptr || head->next == nullptr){
|
||||
return head;
|
||||
}
|
||||
ListNode * pre = head;
|
||||
ListNode * low = new ListNode(0);
|
||||
low->next = pre;
|
||||
ListNode * ret = new ListNode(-1);
|
||||
ret = low;
|
||||
while(pre != nullptr && pre->next != nullptr) {
|
||||
if (pre->val == pre->next->val) {
|
||||
while (pre != nullptr && pre->next != nullptr && pre->val == pre->next->val) {
|
||||
pre = pre->next;
|
||||
}
|
||||
pre = pre->next;
|
||||
low->next = pre;
|
||||
}
|
||||
else{
|
||||
pre = pre->next;
|
||||
low = low->next;
|
||||
}
|
||||
}
|
||||
return ret->next;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
/**
|
||||
* Definition for singly-linked list.
|
||||
@ -75,7 +77,41 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* partition(ListNode* head, int x) {
|
||||
if (head == nullptr) {
|
||||
return head;
|
||||
}
|
||||
ListNode * pro = head;
|
||||
ListNode * big = new ListNode(-1);
|
||||
ListNode * small = new ListNode(-1);
|
||||
ListNode * headbig = big;
|
||||
ListNode * headsmall =small;
|
||||
//分
|
||||
while (pro != nullptr) {
|
||||
//大于时,放到 big 链表上
|
||||
if (pro->val >= x) {
|
||||
big->next = pro;
|
||||
big = big->next;
|
||||
// 小于放到 small 链表上
|
||||
}else {
|
||||
small->next = pro;
|
||||
small = small->next;
|
||||
}
|
||||
pro = pro->next;
|
||||
}
|
||||
//细节
|
||||
big->next = nullptr;
|
||||
//合
|
||||
small->next = headbig->next;
|
||||
return headsmall->next;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
@ -34,6 +34,12 @@
|
||||
|
||||
是不是很容易理解,下面我们来看代码吧。
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode reverseBetween(ListNode head, int left, int right) {
|
||||
@ -79,3 +85,47 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* reverseBetween(ListNode* head, int left, int right) {
|
||||
ListNode * temp = new ListNode(-1);
|
||||
temp->next = head;
|
||||
ListNode * pro = temp;
|
||||
//来到 left 节点前的一个节点
|
||||
int i = 0;
|
||||
for (; i < left-1; ++i) {
|
||||
pro = pro->next;
|
||||
}
|
||||
// 保存 left 节点前的第一个节点
|
||||
ListNode * leftNode = pro;
|
||||
for (; i < right; ++i) {
|
||||
pro = pro->next;
|
||||
}
|
||||
// 保存 right 节点后的节点
|
||||
ListNode * rightNode = pro->next;
|
||||
//切断链表
|
||||
pro->next = nullptr;
|
||||
ListNode * newhead = leftNode->next;
|
||||
leftNode->next = nullptr;
|
||||
leftNode->next = rever(newhead);
|
||||
//重新接头
|
||||
newhead->next = rightNode;
|
||||
return temp->next;
|
||||
}
|
||||
ListNode * rever (ListNode * head) {
|
||||
ListNode * low = nullptr;
|
||||
ListNode * pro = head;
|
||||
while (pro != nullptr) {
|
||||
ListNode * temp = pro;
|
||||
pro = pro->next;
|
||||
temp->next = low;
|
||||
low = temp;
|
||||
}
|
||||
return low;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -26,14 +26,18 @@
|
||||
|
||||
### HashSet
|
||||
|
||||
这个方法是比较简单的,主要思路就是,先遍历一个链表将链表的所有值都存到哈希表中,然后再遍历另一个链表,如果发现某个结点在哈希表中已经存在那我们直接返回该节点即可,代码也很简单。
|
||||
这个方法是比较简单的,主要思路就是,先遍历一个链表将链表的所有值都存到Hashset中,然后再遍历另一个链表,如果发现某个结点在Hashset中已经存在那我们直接返回该节点即可,代码也很简单。
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
public class Solution {
|
||||
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
|
||||
ListNode tempa = headA;
|
||||
ListNode tempb = headB;
|
||||
//定义hash表
|
||||
//定义Hashset
|
||||
HashSet<ListNode> arr = new HashSet<ListNode>();
|
||||
while (tempa != null) {
|
||||
arr.add(tempa);
|
||||
@ -45,12 +49,36 @@ public class Solution {
|
||||
}
|
||||
tempb = tempb.next;
|
||||
}
|
||||
return tempb;
|
||||
|
||||
return tempb;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
|
||||
ListNode * tempa = headA;
|
||||
ListNode * tempb = headB;
|
||||
//定义Hashset, cpp对应set
|
||||
set <ListNode *> arr;
|
||||
while (tempa != nullptr) {
|
||||
arr.insert(tempa);
|
||||
tempa = tempa->next;
|
||||
}
|
||||
while (tempb != nullptr) {
|
||||
if (arr.find(tempb) != arr.end()) {
|
||||
return tempb;
|
||||
}
|
||||
tempb = tempb->next;
|
||||
}
|
||||
return tempb;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
下面这个方法比较巧妙,不是特别容易想到,大家可以自己实现一下,这个方法也是利用我们的双指针思想。
|
||||
|
||||
下面我们直接看动图吧,特别直观,一下就可以搞懂。
|
||||
@ -59,6 +87,10 @@ public class Solution {
|
||||
|
||||
是不是一下就懂了呀,我们利用双指针,当某一指针遍历完链表之后,然后掉头去另一个链表的头部,继续遍历。因为速度相同所以他们第二次遍历的时候肯定会相遇,是不是很浪漫啊!
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
public class Solution {
|
||||
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
|
||||
@ -76,7 +108,25 @@ public class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
|
||||
//定义两个节点
|
||||
ListNode * tempa = headA;
|
||||
ListNode * tempb = headB;
|
||||
//循环
|
||||
while (tempa != tempb) {
|
||||
//如果不为空就指针下移,为空就跳到另一链表的头部
|
||||
tempa = tempa != nullptr ? tempa->next: headB;
|
||||
tempb = tempb != nullptr ? tempb->next: headA;
|
||||
}
|
||||
return tempa;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
好啦,链表的题目就结束啦,希望大家能有所收获,下周就要更新新的题型啦,继续坚持,肯定会有收获的。
|
||||
|
||||
|
@ -27,8 +27,13 @@
|
||||
|
||||
![合并数组](https://cdn.jsdelivr.net/gh/tan45du/photobed@master/photo/合并数组.216f4nn4lti8.gif)
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
|
||||
class Solution {
|
||||
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
|
||||
ListNode headpro = new ListNode(-1);
|
||||
ListNode headtemp = headpro;
|
||||
while (l1 != null && l2 != null) {
|
||||
@ -45,7 +50,33 @@
|
||||
}
|
||||
headpro.next = l1 != null ? l1:l2;
|
||||
return headtemp.next;
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
|
||||
ListNode * headpro = new ListNode(-1);
|
||||
ListNode * headtemp = headpro;
|
||||
while (l1 != nullptr && l2 != nullptr) {
|
||||
//接上大的那个
|
||||
if (l1->val >= l2->val) {
|
||||
headpro->next = l2;
|
||||
l2 = l2->next;
|
||||
}
|
||||
else {
|
||||
headpro->next = l1;
|
||||
l1 = l1->next;
|
||||
}
|
||||
headpro = headpro->next;
|
||||
}
|
||||
headpro->next = l1 != nullptr ? l1: l2;
|
||||
return headtemp->next;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -26,14 +26,20 @@
|
||||
|
||||
### HashSet
|
||||
|
||||
这个方法是比较简单的,主要思路就是,先遍历一个链表将链表的所有值都存到哈希表中,然后再遍历另一个链表,如果发现某个结点在哈希表中已经存在那我们直接返回该节点即可,代码也很简单。
|
||||
这个方法是比较简单的,主要思路就是,先遍历一个链表将链表的所有值都存到Hashset中,然后再遍历另一个链表,如果发现某个结点在Hashset中已经存在那我们直接返回该节点即可,代码也很简单。
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
public class Solution {
|
||||
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
|
||||
ListNode tempa = headA;
|
||||
ListNode tempb = headB;
|
||||
//定义hash表
|
||||
//定义Hashset
|
||||
HashSet<ListNode> arr = new HashSet<ListNode>();
|
||||
while (tempa != null) {
|
||||
arr.add(tempa);
|
||||
@ -51,6 +57,31 @@ public class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode * getIntersectionNode(ListNode *headA, ListNode *headB) {
|
||||
ListNode * tempa = headA;
|
||||
ListNode * tempb = headB;
|
||||
//定义Hashset
|
||||
set <ListNode *> arr;
|
||||
while (tempa != nullptr) {
|
||||
arr.insert(tempa);
|
||||
tempa = tempa->next;
|
||||
}
|
||||
while (tempb != nullptr) {
|
||||
if (arr.find(tempb) != arr.end()) {
|
||||
return tempb;
|
||||
}
|
||||
tempb = tempb->next;
|
||||
}
|
||||
return tempb;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
下面这个方法比较巧妙,不是特别容易想到,大家可以自己实现一下,这个方法也是利用我们的双指针思想。
|
||||
|
||||
下面我们直接看动图吧,特别直观,一下就可以搞懂。
|
||||
@ -59,6 +90,12 @@ public class Solution {
|
||||
|
||||
是不是一下就懂了呀,我们利用双指针,当某一指针遍历完链表之后,然后掉头去另一个链表的头部,继续遍历。因为速度相同所以他们第二次遍历的时候肯定会相遇,是不是很浪漫啊!
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
public class Solution {
|
||||
public ListNode getIntersectionNode (ListNode headA, ListNode headB) {
|
||||
@ -68,15 +105,33 @@ public class Solution {
|
||||
//循环
|
||||
while (tempa != tempb) {
|
||||
//如果不为空就指针下移,为空就跳到另一链表的头部
|
||||
tempa = tempa!=null ? tempa.next:headB;
|
||||
tempb = tempb!=null ? tempb.next:headA;
|
||||
tempa = tempa != null ? tempa.next: headB;
|
||||
tempb = tempb != null ? tempb.next: headA;
|
||||
}
|
||||
return tempa;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode * getIntersectionNode(ListNode *headA, ListNode *headB) {
|
||||
//定义两个节点
|
||||
ListNode * tempa = headA;
|
||||
ListNode * tempb = headB;
|
||||
//循环
|
||||
while (tempa != tempb) {
|
||||
//如果不为空就指针下移,为空就跳到另一链表的头部
|
||||
tempa = tempa != nullptr ? tempa->next: headB;
|
||||
tempb = tempb != nullptr ? tempb->next: headA;
|
||||
}
|
||||
return tempa;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
好啦,链表的题目就结束啦,希望大家能有所收获,下周就要更新新的题型啦,继续坚持,肯定会有收获的。
|
||||
|
||||
|
@ -30,6 +30,10 @@
|
||||
|
||||
感觉这个方法既巧妙又简单,大家可以自己动手打一下,这个题目是经典题目。
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode getKthFromEnd (ListNode head, int k) {
|
||||
@ -58,3 +62,34 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode * getKthFromEnd(ListNode * head, int k) {
|
||||
//特殊情况
|
||||
if (head == nullptr) {
|
||||
return head;
|
||||
}
|
||||
//初始化两个指针
|
||||
ListNode * pro = new ListNode(-1);
|
||||
ListNode * after = new ListNode(-1);
|
||||
//定义指针指向
|
||||
pro = head;
|
||||
after = head;
|
||||
//先移动绿指针到指定位置
|
||||
for (int i = 0; i < k-1; i++) {
|
||||
pro = pro->next;
|
||||
}
|
||||
//两个指针同时移动
|
||||
while (pro->next != nullptr) {
|
||||
pro = pro->next;
|
||||
after = after->next;
|
||||
}
|
||||
//返回倒数第k个节点
|
||||
return after;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -48,6 +48,10 @@
|
||||
|
||||
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210321131249789.gif)
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode middleNode(ListNode head) {
|
||||
@ -64,3 +68,21 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
public:
|
||||
ListNode* middleNode(ListNode* head) {
|
||||
ListNode * fast = head;//快指针
|
||||
ListNode * slow = head;//慢指针
|
||||
//循环条件,思考一下跳出循环的情况
|
||||
while (fast != nullptr && fast->next != nullptr) {
|
||||
fast = fast->next->next;
|
||||
slow = slow->next;
|
||||
}
|
||||
//返回slow指针指向的节点
|
||||
return slow;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
@ -69,6 +69,12 @@
|
||||
|
||||
注:这里需要注意得时,链表遍历结束,我们应该跳出循环,但是我们的nlist仍在尾部添加了1节点,那是因为跳出循环时,summod值为1,所以我们需要在尾部再添加一个节点。
|
||||
|
||||
|
||||
|
||||
**题目代码**
|
||||
|
||||
Java Code:
|
||||
|
||||
```java
|
||||
class Solution {
|
||||
public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
|
||||
@ -108,3 +114,45 @@ class Solution {
|
||||
}
|
||||
```
|
||||
|
||||
C++ Code:
|
||||
|
||||
```cpp
|
||||
class Solution {
|
||||
public:
|
||||
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
|
||||
//返回链表
|
||||
ListNode * nList = new ListNode(-1);
|
||||
ListNode * tempnode = nList;
|
||||
//用来保存进位值,初始化为0
|
||||
int summod = 0;
|
||||
while(l1 != nullptr || l2 != nullptr) {
|
||||
//如果l1的链表为空则l1num为0,若是不为空,则为链表的节点值
|
||||
//判断是否为空,为空就设为0
|
||||
int l1num = l1 == nullptr ? 0 : l1->val;
|
||||
int l2num = l2 == nullptr ? 0 : l2->val;
|
||||
//将链表的值和进位值相加,得到为返回链表的值
|
||||
int sum = l1num + l2num + summod;
|
||||
//更新进位值,例18/10=1,9/10=0
|
||||
summod = sum / 10;
|
||||
//新节点保存的值,18 % 8=2,则添加2
|
||||
sum = sum % 10;
|
||||
//添加节点
|
||||
tempnode->next = new ListNode(sum);
|
||||
//移动指针
|
||||
tempnode = tempnode->next;
|
||||
if (l1 != nullptr) {
|
||||
l1 = l1->next;
|
||||
}
|
||||
if (l2 != nullptr) {
|
||||
l2 = l2->next;
|
||||
}
|
||||
}
|
||||
//最后根据进位值判断需不需要继续添加节点
|
||||
if (summod == 1) {
|
||||
tempnode->next = new ListNode(summod);
|
||||
}
|
||||
return nList->next;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user