通过先删除或在开始时添加一个已删除节点来最小化链表的第一个节点
给定一个单链表和一个整数K ,任务是在K个操作中使第一个节点值尽可能小,其中每个操作:
- 选择链表的第一个节点并将其删除。
- 在链表的开头添加一个先前删除的节点。
例子:
Input: list: 1->4->2->5->3, K=4
Output:1
Explanation:
1st operation-> Remove 1st Node, After performing operation linked list become 4->2->5->3
2nd operation-> Remove 1st Node, After performing operation linked list become 2->5->3
3rd operation-> Remove 1st Node, After performing operation linked list become 5->3
4th operation-> Add previously removed Node (i.e. 1), After performing operation linked list become 1->5->3
Input: Linked List: 5, K = 1
Output: -1
Explanation: Only possible operation is to delete the first node.
If that operation is performed then the list will be empty.
方法:可以通过以下观察来解决问题:
In first K-1 operations, the K-1 value of the starting can be removed. So currently at Kth node. Now in the last operation there are two possible choice:
- Either remove the current starting node (optimal if the value of the (K+1)th node is smaller than the smallest amongst first K-1 already removed elements)
- Add the smallest from the already removed K-1 elements (optimal when the (K+1)th node has higher value than the smallest one)
请按照以下步骤解决问题:
- 如果K = 0 ,则返回第一个节点值。
- 如果K = 1 ,则返回第二个节点值(如果有),否则返回 -1(因为在K操作之后列表不存在)。
- 如果链表的大小为 1,则在每个奇数运算(即 1、3、5、...)中,返回 -1,否则返回第一个节点值(原因同上)。
- 如果K > 2 ,则:
- 遍历前K-1个节点并找出最小值。
- 将该最小值与第(K+1) 个节点值进行比较。
- 如果第 (K+1) 个值小于之前的最小值,则使用第 (K+1) 个节点值对其进行更新。
- 返回最小值。
下面是上述方法的实现:
C++
// C++ program for above approach
#include
using namespace std;
// Structure of node of singly linked list
struct Node {
int data;
Node* next;
Node(int x)
{
data = x;
next = NULL;
}
};
// Inserting new node
// at the beginning of the linked list
void push(struct Node** head_ref,
int new_data)
{
// Create a new node with the given data.
struct Node* new_node = new Node(new_data);
// Make the new node point to the head.
new_node->next = (*head_ref);
// Make the new node as the head node.
(*head_ref) = new_node;
}
// Function to find the
// minimum possible first node
int FirstNode(Node* head, int K)
{
if (K == 0) {
return head->data;
}
if (K == 1) {
return (head->next == NULL) ? -1 : head->next->data;
}
if (head->next == NULL) {
return (K % 2) ? -1 : head->data;
}
int ans = INT_MAX;
int i = 0;
// Traverse 1st K-1 Nodes and find out
// minimum node
// value
while (head != NULL && i < K - 1) {
if (head->data < ans)
ans = head->data;
head = head->next;
i++;
}
// Check whether Linked list have (K+1)th
// Node or not
if (head && head->next != NULL) {
// Update ans with minimum of 1st K-1
// nodes and the (K+1)th Node.
ans = min(ans, head->next->data);
}
return ans;
}
// Driver code
int main()
{
int K = 4;
// Create an empty singly linked list
struct Node* head = NULL;
// Insert values in Linked List
push(&head, 3);
push(&head, 5);
push(&head, 2);
push(&head, 4);
push(&head, 1);
// Call FirstNode function
cout << FirstNode(head, K);
return 0;
}
1
时间复杂度: O(K)
辅助空间: O(1)