투포인터 

- 배열이나 리스트에서 '두개의 포인터를' 사용하여 '특정 조건을 만족하는 부분 구간'을 효율적으로 탐색하는 알고리즘

- 정렬되어 있는, 배열 또는 리스트의 경우에 사용함

 

투 포인터 방법

1단계 : 배열 또는 리스트의 시작 위치에서 첫 번째 포인터와 두번째 포인터 설정

2단계 : 두 포인터 사이의 구간을 조사하고 조건 확립

3단계 : 조건 만족할 경우, 종료

4단계 : 조건이 만족하지 않을 경우, 첫번째 또는 두번째 포인터로 이동

5단계 : 2단계로 돌아가 재수행

 

투 포인터 시간 복잡도

- 투 포인터 알고리즘은 선형시간 복잡도를 가지며, 효율적이다.

- 한번의 반복으로 모든 요소를 처리

- 빅오 표기법으로  O(N), 배열 또는 리스트의 크기에 비례하여 수행시간 증가

 

투 포인터의 종류

1) 고정 길이 슬라이딩 윈도우

  - 고정된 길이의 윈도우를 사용하여 배열이나 리스트 탐색

  - 아래 이미지는 위도우 사이즈를 3으로 고정한 후 움직이는 모습

  - 배열의 합 또는 평균을 계산하는 문제에 사용됨

2) 가변 길이 슬라이딩 윈도우

  - 가변 길이의 윈도우를 사용하여 배열이나 리스트를 탐색

  - 최소 길이 부분 배열이나, 최대 길이 부분 배열을 찾는 문제에 사용됨

 

 

3) 두 포인터의 합과 차

  - 배열이나 리스트에서 두개의 포인터를 사용하여 합이나 차를 계산하는 문제를 해결

  - 두 요소의 합이나 차가 주어진 값과 일치하는지 확인하는 문제에 사용됨

 

 

 

 

 

투 포인터 단계별 백준문제

https://www.acmicpc.net/step/59

 

 


쉘스크립트로 자동화를 하려고하는데, 아래와 같이 에러가 발생했다.

​

warning: here-document at line 1 delimited by end-of-file (wanted `EOF')

​

쉘 스크립트 자체를 공부하지않고, 필요한 부분만 확인하면서 개발했기에... 해결하는데 너무 오래 걸렸다.

​

해결방법은 너무 간단하다.....

​

원인

EOF 앞 또는 뒤에 공백이나 탭이 있을 경우, 발생한다.

​

​

해결방법

공백이나 탭을 삭제하기

DFS를 이용한 문제였습니다.

 

package algoridm;

import java.util.*;
public class 섬의개수 {

	private static int w;
	private static int h;
	
	private static int[][] arr;
	private static boolean[][] visited;
	private static int[] dx = {0, 0, 1, 1, -1, -1, 1, -1};
	private static int[] dy = {1,-1, 1, -1, 1, -1, 0, 0};
	
	private static int cnt = 0;
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true) {
			cnt = 0;
			w = sc.nextInt();
			h = sc.nextInt();
			if(w==0 &&h==0)break;
			sc.nextLine();
			

			arr = new int[h][w];
			visited = new boolean[h][w];
			
			for(int i=0; i<h;i++) {
				String str = sc.nextLine().replace(" ", "");
				for(int j=0; j<str.length();j++) {
					arr[i][j] = str.charAt(j)-'0';
				}
			}
			
			for(int i=0; i<h;i++) {
				for(int j=0; j<w;j++) {
					if(!visited[i][j] && arr[i][j]==1) {
						dfs(i,j);
						cnt++;
					}
				}
			}
			System.out.println(cnt);
		}
	}
	
	private static void dfs(int x, int y) {
		visited[x][y] = true;
		
		for(int i=0; i<8;i++) {
			int nx = x + dx[i];
			int ny = y + dy[i];
			
			if(nx>=0 && ny >=0 && nx<h && ny<w) {
				if(!visited[nx][ny] && arr[nx][ny]==1) dfs(nx,ny);
			}
		}
	}

}

 

문제를 풀다가 하나 실수 떄문에 시간이 엄청 오래 걸렸네요...

깊이우선탐색을 통해 푸는 방법은 맞았으나,

어이없게도 입력받는 데이터를 제대로 가공하지 못해서

정답이 나오지 않았습니다. ㅠㅠ

​

입력 받았을떄 공백으로 인해서 값이... 후.. 생각만해도 끔찍ㅎㅎ

뭐.. 다시 안그러면 되겠죠 ㅎㅎㅎ

​

점점 깊이우선탐색을 사용하는데 익숙해 지고 있습니다.

​

여기서 팁아닌 팁은 보통 탐색을할때 상하좌우 4가지 방법으로 움직이지만

대각선까지 포함되므로

소스에 있는 dx배열과 dy배열을 잘보셔야 될거 같습니다.

​

다른거는 딱히 어려운건 없었습니다. ㅎㅎ

​

​

​

https://www.acmicpc.net/problem/4963

 

1단계 무난히 풀수 있는 문제 였습니다.

​

if문과 for문만 잘 사용한다면 쉽게 풀 수 있을거 같습니다

 

정렬해서 푸는 방법도 있지만, 저는 정렬을 사용하지 않고 풀었습니다.

 

 

나의 풀이

class Solution {
    public int[] solution(int[] lottos, int[] win_nums) {
        int[] answer = new int[2];
        
        for(int i=0; i<lottos.length;i++){
            if(lottos[i]==0){//로또 번호 0인값 체크
                answer[0]++; // 0번째 인덱스에는 최대 많이 맞춘 갯수를 넣기 위해 추가
                continue;
            }
            for(int j=0; j<win_nums.length;j++){
                if(lottos[i]== win_nums[j]){ //로또번호가 맞을 경우
                    answer[0]++;// 0번째 인덱스에는 최대한 많이 맞춘 갯수를 넣기위해 추가
                    answer[1]++;// 1번째 인덱스는 가장 적게 맞춘 갯수를 넣기 위해 일치할때만 증가
                    break;
                }
            }
        }
  
        for(int i=0; i<2;i++){ // 0번째, 1번째 인덱스
             if(answer[i]==6)answer[i]=1; //1등
             else if(answer[i]==5)answer[i]=2;//2등
             else if(answer[i]==4)answer[i]=3;//3등
             else if(answer[i]==3)answer[i]=4;//4등
             else if(answer[i]==2)answer[i]=5;//5등
             else answer[i]=6;//꼴등
        }
        return answer;
    }
}

 

 

 


다른 풀이

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int[] solution(int[] lottos, int[] win_nums) {
        Map<Integer, Boolean> map = new HashMap<Integer, Boolean>();
        int zeroCount = 0;

        for(int lotto : lottos) {
            if(lotto == 0) {
                zeroCount++;
                continue;
            }
            map.put(lotto, true);
        }


        int sameCount = 0;
        for(int winNum : win_nums) {
            if(map.containsKey(winNum)) sameCount++;
        }

        int maxRank = 7 - (sameCount + zeroCount);
        int minRank = 7 - sameCount;
        if(maxRank > 6) maxRank = 6;
        if(minRank > 6) minRank = 6;

        return new int[] {maxRank, minRank};
    }
}

 

아직 검색이나 자동완성이 없는 경우

 

Map, Set 같은 자료구조를 사용하기 힘들어서 시도해보지 못했다.

​

자동완성이 없을 때도 사용 할 수 있게 연습을 계속 해야겠다.

 

https://programmers.co.kr/learn/courses/30/lessons/77484?language=java#

BFS를 이용한 문제 였습니다.

​

Node 클래스를 만들어 x,y의 값을 저장하여 사용하며,

​

dx,dy 배열를 이용하여 위치를 상,하,좌,우 이동하면서 탐색 할 수 있게 하였습니다.

 

import java.util.*;

class Node{
	int x;
	int y;
	
	public Node(int x, int y) {
		this.x = x;
		this.y = y;
	}
	
	public int getX() {
		return this.x;
	}
	
	public int getY() {
		return this.y;
	}
	
}

public class 미로탈출 {
	
	static int N,M;
	static int[][] grph = new int[201][201];
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		M = sc.nextInt();
		sc.nextLine(); //Remove buffer
		for(int i=1; i<=N;i++) {
			String str = sc.nextLine();
			for(int j=1; j<=M;j++) {
				grph[i][j]= str.charAt(j-1)-'0';
			}
		}
		
		System.out.println(bfs(1,1));

	}
	
	public static int bfs(int x, int y) {
		
		int dx[] = {1,-1,0,0};
		int dy[] = {0,0,1,-1};
		
		Queue<Node> queue = new LinkedList<>();
		queue.offer(new Node(x,y));
		
		while(!queue.isEmpty()) {
			Node node = queue.poll();
			x = node.getX();
			y = node.getY();
			for(int i=0 ; i<4;i++) {
				int nx = x+dx[i];
				int ny = y+dy[i];
				if(nx<1 || nx>N  || ny<1 || ny>M) continue;
				if(grph[nx][ny]==0)continue;
				if(grph[nx][ny]==1) {
					grph[nx][ny] = grph[x][y]+1;
					queue.offer(new Node(nx,ny));
				}
			}
		}
		
		return grph[N][M];
	}
	
}

https://www.acmicpc.net/problem/2178

 

2178번: 미로 탐색

첫째 줄에 두 정수 N, M(2 ≤ N, M ≤ 100)이 주어진다. 다음 N개의 줄에는 M개의 정수로 미로가 주어진다. 각각의 수들은 붙어서 입력으로 주어진다.

www.acmicpc.net

 

 

아직 BFS와 DFS를 사용하여 문제를 풀이하는데

익숙하지 않아,

 

복습과 여러문제를 풀어서

 

익숙해 져야할거 같습니다.

​

+ Recent posts