Algorithm/연결리스트
[틀림] 프로그래머스 표편집 c++ // 연결리스트 직접구현 하는방법, 삽입삭제 되돌리기는 연결리스트(직접구현)!
Mini_96
2023. 11. 23. 14:13
https://school.programmers.co.kr/learn/courses/30/lessons/81303
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
1. 고찰
stl의 list<int>를 쓰면 풀수없는듯 하다.
이유 : prev,next 가 없음..
- 삽입삭제, 되돌리기는 연결리스트(직접구현)!
- 삭제된 노드도 prev,next가 남아있기때문에 복원이 ez하다!
2.전체코드
#include <bits/stdc++.h>
using namespace std;
struct Node{
int n;
Node* prev;
Node* next;
Node(int n, Node* prev, Node* next) :
n(n),prev(prev),next(next){}
};
//(삽입,)삭제가 빈번할때는 리스트!
//행갯수n , 첫인덱스 k
string solution(int n, int k, vector<string> cmd) {
string answer(n,'X'); //n만큼 X로 채우기
//노드연결
Node* cursor = new Node(0,NULL,NULL); //첫노드
for(int i=1;i<n;++i){
cursor->next=new Node(i,cursor,NULL);
cursor=cursor->next;
}
// k로 커서 이동
//n=4, k=1 일때 : 0 , 1, 2, 3
//3에서 1로 2회이동해야함
//2회==n-k-1회
for(int i=0;i<n-k-1;i++) cursor = cursor->prev;
stack<Node*> del;
for(auto op : cmd){
if(op[0]=='U'){
//if(k==0) continue;
int x=stoi(op.substr(2));
while(x--) cursor=cursor->prev;
}
else if(op[0]=='D'){
//if(k==n-1) continue;
int x=stoi(op.substr(2));
while(x--) cursor=cursor->next;
}
else if(op=="C"){
del.push(cursor); //삭제할노드 포인터 넣기
//앞노드가 있는경우 , 그림그려보면 쉬움
if(cursor->prev != NULL) cursor->prev->next=cursor->next; // < -연결
if(cursor->next!=NULL) cursor->next->prev = cursor->prev; // -> 연결
//마지막노드인경우 이전노드 가르키도록
if(cursor->next==NULL) cursor = cursor->prev;
else cursor = cursor->next; //마지막노드가아니면 다음노드를 가르킴
}
else if(op=="Z"){
auto r = del.top(); del.pop();
if(r->prev != NULL) r->prev->next=r; // -> 다시연결
if(r->next != NULL) r->next->prev=r; // <- 다시연결
}
}
//정답채우기
answer[cursor->n]='O';
// <-로 가면서 살아있는 idx에 O 채우기
while(cursor->prev!=NULL){
answer[cursor->prev->n]='O';
cursor=cursor->prev;
}
// ->로 가면서 살아있는 idx에 O 채우기
while(cursor->next!=NULL){
answer[cursor->next->n]='O';
cursor=cursor->next;
}
return answer;
}
* 25.5.9. 2회독
시도1
자바가 제공하는 링크드 리스트로 구현?
안되는이유 : cursor(현재위치) 를 찾기위해서 O(N)이 걸림 -> 직접 구현해야함
시도2
배열 && soft delete?
삭제시) 마지막행인지 보려면 O(N)이 필요함. -> 팬윅트리, 세그트리로 개선가능 하다고 함.
풀이( 직접구현한 양방향 연결리스트)
1. 링크드 리스트 만들기
2. 크게 3가지 경우로 나누어 생각 : 맨앞, 맨뒤, 중간
복구시 삭제된 노드의 포인터가 살아있음을 이용해 O(1)만에 복구가능!
3. 정답을 만들기위해 removed 필드추가, 배열에 담아놓기
전체코드
import java.util.*;
class Node {
int val;
boolean removed;
Node prev,next;
Node(int val, boolean removed, Node prev, Node next){
this.val=val;
this.removed=removed;
this.prev=prev;
this.next=next;
}
void setPrev(Node prev){
this.prev=prev;
}
void setNext(Node next){
this.next=next;
}
}
class Solution {
public String solution(int n, int k, String[] cmd) {
String answer = "";
Node [] arr = new Node[n];
Node first = new Node(0,false,null,null);
Node prev=first;
arr[0]=first;
for(int i=1;i<n;++i){
Node node = new Node(i,false,null,null);
arr[i]=node;
prev.setNext(node);
node.setPrev(prev);
prev=node;
}
Node cursor=first;
while(k-- > 0){
cursor = cursor.next;
}
System.out.println(cursor.val);
// while(cursor.next!=null){
// System.out.println(cursor.val);
// cursor = cursor.next;
// }
// System.out.println(cursor.val);
Stack<Node> stk = new Stack<>();
for(String op : cmd){
if(op.charAt(0)=='U'){
int x = Integer.parseInt(op.substring(2)); //주의 : x는 30만 이하임. 한자리 아님!, 2~끝까지
while(x-- >0){
cursor = cursor.prev;
}
}
else if(op.charAt(0)=='D'){
int x = Integer.parseInt(op.substring(2));
while(x-- >0){
cursor = cursor.next;
}
}
else if(op.charAt(0)=='C'){
cursor.removed=true;
stk.push(cursor);
if(cursor.next==null){ //막행인경우
cursor = cursor.prev;
cursor.next=null;
}
else if(cursor.prev==null){ //첫행인경우
cursor = cursor.next;
cursor.prev=null;
}
else{
cursor.prev.next = cursor.next;
cursor.next.prev = cursor.prev;
cursor = cursor.next;
}
}
else if(op.charAt(0)=='Z'){
Node node = stk.pop();
node.removed=false;
if(node.next==null){ //막행인경우
node.prev.next=node;
}
else if(node.prev==null){ //첫행인경우
node.next.prev=node;
}
else{
node.prev.next=node;
node.next.prev=node;
}
}
}
StringBuilder sb = new StringBuilder();
for(int i=0;i<n;++i){
if(arr[i].removed==true){
sb.append("X");
}
else{
sb.append("O");
}
}
return sb.toString();
}
}
헤맸던 부분
이동할 칸수 X는 한자리가 아님, 30만까지가능 -> substring(2) //2~끝까지로 추출해야함.
정답은 어떻게 만들지? -> 배열에 노드를 넣어놓고 removed를 체크.