[문제 설명]

n 개의 음이 아닌 정수들이 있습니다. 이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다. 예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.

-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3

사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자르 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution  함수를 작성해주세요.

 

[제한 사항]

- 주어지는 숫자의 개수는 2개 이상 20개 이하입니다.

- 각 숫자는 1 이상 50 이하인 자연수입니다.

- 타겟 넘버는 1 이상 1000 이하인 자연수입니다.

 

[입출력 예]

numbers target return
[1, 1, 1, 1, 1] 3 5
[4, 1, 2, 1] 4 2

 

class Solution{
	static int answer = 0;
	public int solution(int[] numbers, int target){        
        dfs(numbers, target, 0, 0);
        
        return answer;
    }
    
    private static void dfs(int[] numbers, int target, int depth, int sum){
    	if(depth == numbers.length){
        	if(sum == target) 
            	answer++;
        }else{
        	dfs(numbers, target, depth + 1, sum + numbers[depth]);
            dfs(numbers, target, depth + 1, sum - numbers[depth]);
        }     
    }
}

 

DFS를 사용한 이유

- 'numbers' 배열의 모든 원소들에 대해 더하거나 빼는 모든 가능한 조합을 탐색할 수 있다. 이는 가능한 모든 경우의 수를 확인하는데 적합

- DFS를 사용하면 재귀적으로 문제를 간결하게 해결할 수 있다. 코드가 비교적 단순하며 가독성이 좋음.

'JAVA > java' 카테고리의 다른 글

프로그래머스 2단계_시소 짝꿍 (자바)  (1) 2024.06.25
자바로 크롤링 하는 방법  (0) 2023.01.20

문제)

어느 공원 놀이터에는 시소가 하나 설치되어 있습니다. 이 시소는 중심으로부터 2(m), 3(m), 4(m) 거리의 지점에 좌석이 하나씩 있습니다.
이 시소를 두 명이 마주 보고 탄다고 할 때, 시소가 평형인 상태에서 각각에 의해 시소에 걸리는 토크의 크기가 서로 상쇄되어 완전한 균형을 이룰 수 있다면 그 두 사람을 시소 짝꿍이라고 합니다. 즉, 탑승한 사람의 무게와 시소 축과 좌석 간의 거리의 곱이 양쪽 다 같다면 시소 짝꿍이라고 할 수 있습니다.
사람들의 몸무게 목록 weights이 주어질 때, 시소 짝꿍이 몇 쌍 존재하는지 구하여 return 하도록 solution 함수를 완성해주세요.


제한 사항

  • 2 ≤ weights의 길이 ≤ 100,000
  • 100 ≤ weights[i] ≤ 1,000
    • 몸무게 단위는 N(뉴턴)으로 주어집니다.
    • 몸무게는 모두 정수입니다.

입출력 예

weights result
[100,180,360,100,270] 4

 

문제 이해)

- 시소는 중심으로부터 2, 3, 4 거리의 지점에 좌석이 하나씩 있음.

- weights의 길이가 100,000 이기 때문에 시간 복잡도 고려해야 함.

 

import java.util.*;

class Solution {
    public long solution(int[] weights) {
        long answer = 0;
    
        Arrays.sort(weights);
        Map<Double, Integer> map = new HashMap<>();
        
        for(int i : weights){
            double a = i * 1.0;
            double b = (i * 2.0) / 3.0;
            double c = (i * 1.0) / 2.0;
            double d = (i * 3.0) / 4.0;
            
            if(map.containsKey(a)) answer += map.get(a);
            if(map.containsKey(b)) answer += map.get(b);
            if(map.containsKey(c)) answer += map.get(c);
            if(map.containsKey(d)) answer += map.get(d);
            
            map.put((i * 1.0), map.getOrDefault((i * 1.0), 0) + 1);
        }
        
        
        return answer;
    }
}

 

 

- weights 정렬하였기 때문에 키값은 크거나 같을 수 밖에 없음. 그래서 [1.0], [2.0/3.0], [2.0/4.0 -> 1.0/2.0], [3.0/4.0] 으로 거리 고려하면 됨.

 

 

'JAVA > java' 카테고리의 다른 글

프로그래머스 2단계_타겟 넘버(자바)  (0) 2024.07.03
자바로 크롤링 하는 방법  (0) 2023.01.20

크롤링을 통해 데이터를 수집하는 방법에 대해 알아보려 한다.

 

자바에서는 JSOUP이라는 라이브러리를 활용한다. 

위키 백과에 따르면 JSOUP은 HTML 문서에 저장된 데이터를 구문, 분석, 추출 및 조작하도록 설계된 오픈 Java 라이브러리라고 이다.

 

java 프로젝트에서 JSOUP을 사용하기 위해서는 JSOUP 라이브러리를 다운로드하여 해당 프로젝트에 설치를 해야 하지만,

스프링 프레임워크를 사용하기에 Maven dependency에 해당 라이브러리를 넣어주려 한다. 

<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.13.1</version>
</dependency>

 

1. 원하는 주소에 접속한다. (네이버 뉴스에 접속)

위와 같이 창이 뜨면 개발자 도구(F12)에 들어간다.

개발자 도구를 사용해 필요한 부분만 찾는다. 뉴스를 부분만 원하기 때문에 뉴스만 해당하는 부분을 클릭해서 해당 태그를 찾는다. class부분에 해당하는 list_body newflash_body를 복사한다. 

지금까지 한 부분을 코딩해 보면 아래와 같다.

String url = "https://news.naver.com/main/list.naver?mode=LS2D&sid2=237&sid1=103&mid=shm&date=20230119&page=1"; 
Document doc = Jsoup.connect(url).get(); //Jsoup에 있는 connect 메소드를 호출하는데 파라미터로 주소 url의 전체 내용을 가져와 document에 저장
Elements elements = doc.getElementsByAttributeValue("class", "list_body newsflash_body"); //class에 해당하는 값을 가지는 모든 tag를 받아야 됨

이런 식으로 위에 클래스 태그에 해당하는 모든 정보들이 나온다. 

 

2. 필요한 태그 분석

위의 태그들을 분석하면 기사 URL, 이미지 URL,  기사 제목,  한 줄 기사 내용이 있다. 더 분석하면 <a>에 기사 제목이 포함되어 있고 <img> 태그에도 기사 제목이 포함되어 있다.  때문에 필요한 정보가 모두 들어가 있는 class = "photo"에 해당하는 속성값의 정보들을 가져올 것이다. 

Element element = elements.get(0); //Elements는 여러 개라는 전제가 포함되기 때문에 elements에 데이터가 하나만 달라고 요청
Elements photoElements = element.getElementsByAttributeValue("class", "photo"); //class 속성에 속성값 photo에 해당하는 정보를 가져옴

Element articleElement = photoElements.get(0); //phtoElements에 해당하는 기사 하나 가져옴
Element aElements = articleElement.select("a").get(0); //a태그 하나만 가져옴

photo 값에 해당하는 정보 출력

기사 URL이 적혀있는 href를 속성값을 가져오기 위해 attr을 사용한다.

String articleUrl = aElement.attr("href"); //attr을 사용해 원하는 속성 키를 넣어 값을 가져옴

기사 링크

같은 방식으로 이미지 URL, 제목을 가져오기 때문에 설명에서는 생략하겠다. (밑에 전체 코드 있으니 참고)

* 제목은 img 태그에 포함된 있기 때문에 이미지 속성을 가져오는 부분 활용. *

 

(2-1) 기사 내용은 다른 페이지에 있기 때문에 기사 주소를 클릭해서 다시 한번 크롤링을 해야 한다. 

Document subDoc = Jsoup.connect(articleUrl).get();
Element contentElement = subDoc.getElementById("dic_area"); //기사 내용이 포함된 id
Sring content = contentElement.text();

- text()는 태그 안에 있는 내용만을 가져온다. 

- id는 유일한 값이 때문에 중복이 없다. 그래서 get()을 이용해 하나만 가져올 필요가 없다.

 

 

 

3. 전체 소스 코드

import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class News {

	public static void main(String[] args) throws IOException{
		
		int page = 3;
		
		for(int j = 0; j < page; j++) {
			String url = "https://news.naver.com/main/list.naver?mode=LS2D&sid2=237&sid1=103&mid=shm&date=20230119&page="+j; 
			Document doc = Jsoup.connect(url).get(); //Jsoup에 있는 connect 메소드를 호출하는데 파라미터로 주소 url의 전체 내용을 가져와 document에 저장
			Elements elements = doc.getElementsByAttributeValue("class", "list_body newsflash_body"); //class에 해당하는 값을 가지는 모든 tag를 받아야 됨
			
			Element element = elements.get(0); //Elements는 여러개라는 전제이기 때문에 elements에 데이터가 하나만 달라고 요청, (첫번쨰 거 요청)
			Elements photoElements = element.getElementsByAttributeValue("class", "photo");
			
			for(int i = 0; i < photoElements.size(); i++) {
				Element articleElement = photoElements.get(i); //photoElements에 해당하는 기사 하나씩 가져옴
				Elements aElements = articleElement.select("a"); //a 태그를 가져옴
				Element aElement = aElements.get(0);
				
		
				String articleUrl = aElement.attr("href"); //attr에 원하는 속성의 키를 넣으면 값을 줌 -> 기사 링크
					
				Element imgElement = aElement.select("img").get(0); //img 태그에 해당하는 하나 가져옴
				String imgUrl = imgElement.attr("src"); //이미지 url
				String title = imgElement.attr("alt"); //기사 제목
				
				System.out.println(articleUrl);
				System.out.println(imgUrl);
				System.out.println(title);
				
				/* 기사 내용
				Document subDoc = Jsoup.connect(articleUrl).get();
				Element contentElement = subDoc.getElementById("dic_area"); //기사 내용에 포함된 id
				String content = contentElement.text(); //text() 태그 안에 값만 나옴 -> <br>이란 거 없이 기사 내용만 나옴
				System.out.println(contentElement.text());
				 */
			}
			
			System.out.println(j+1 + "page 크롤링 종료");
			System.out.println();
		}
	}
}

 

 

 

 

 

 

 

- https://www.youtube.com/watch?v=XiTxFXgSvG8 참고했습니다.

'JAVA > java' 카테고리의 다른 글

프로그래머스 2단계_타겟 넘버(자바)  (0) 2024.07.03
프로그래머스 2단계_시소 짝꿍 (자바)  (1) 2024.06.25

+ Recent posts