>알고리즘 문제
1.문제
문제 설명
비내림차순으로 정렬된 수열이 주어질 때, 다음 조건을 만족하는 부분 수열을 찾으려고 합니다.
- 기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열이어야 합니다.
- 부분 수열의 합은 k입니다.
- 합이 k인 부분 수열이 여러 개인 경우 길이가 짧은 수열을 찾습니다.
- 길이가 짧은 수열이 여러 개인 경우 앞쪽(시작 인덱스가 작은)에 나오는 수열을 찾습니다.
수열을 나타내는 정수 배열 sequence와 부분 수열의 합을 나타내는 정수 k가 매개변수로 주어질 때, 위 조건을 만족하는 부분 수열의 시작 인덱스와 마지막 인덱스를 배열에 담아 return 하는 solution 함수를 완성해주세요. 이때 수열의 인덱스는 0부터 시작합니다.
제한사항
- 5 ≤ sequence의 길이 ≤ 1,000,000
- 1 ≤ sequence의 원소 ≤ 1,000
- sequence는 비내림차순으로 정렬되어 있습니다.
- 5 ≤ k ≤ 1,000,000,000
- k는 항상 sequence의 부분 수열로 만들 수 있는 값입니다.
2. 솔루션
class Solution {
fun solution(sequence: IntArray, k: Int): IntArray {
var answer: IntArray = intArrayOf()
var end=sequence.size-1
var start=sequence.size-1
var sum=sequence[end]
while(true){
while(sum<k){
sum+=sequence[--start]
}
if(sum==k) break
sum-=sequence[end--]
}
while(start>=1&&end>=1&&sequence[end-1]==sequence[end]&&sequence[start-1]==sequence[start]&&sequence[end-1]==sequence[start-1]){
start--
end--
}
answer+=start
answer+=end
return answer
}
}
>숙련 1주차 강의
1. 프래그먼트
(1)프래그먼트란
-액티비티 위에서 동작하는 모듈화된 사용자 인터페이스: 액티비티와 분리되어 독립적으로는 동작 불가
-여러 프래그먼트를 하나의 액티비티에 조합하여 창이 여러개인 UI구축 가능
-한 프래그먼트를 여러 액티비티에서 재사용 가능
(2)프래그먼트와 액티비티
<1>액티비티: 인텐트로 액티비티간 데이터 전달
<2>프래그먼트: 액티비티의 프래그먼트 매니저에서 메소드로 프래그먼트간 데이터 전달
(3)프래그먼트 생명주기
<1>onAttach()
-프래그먼트가 액티비티에 연결될 때 호출
-아직 프래그먼트가 액티비티에 완전히 연결되진 않은 상태
<2>onCreate()
-프래그먼트 생성시 호출
-초기화, 리소스 바인딩등을 수행가능
<3>onCreateView()
-프래그먼트의 레이아웃을 인플레이트
-뷰 생성 및 레이아웃 설정
<4>onViewCreated()
-onCreateView()에서 반환된 View객체가 이 함수에 파라미터로 전달됨
-초기화: View의 초기값을 설정하거나 adapter를 초기화 수행을 이곳에서 함.
<5>onViewStateRestored()
- onViewStateRestored() 함수는 저장해둔 모든 state 값이 Fragment의 View 계층구조에 복원됐을 때 호출된다.
<6>onStart()
-프래그먼트가 사용자에게 보여질 준비완료시 호출
-필요한 리소스 할당 및 애니메이션 시작 가능
<7>onResume()
-프래그먼트가 사용자와 상호작용 가능 상태일때 호출
-프래그먼트가 포그라운드에 있을때 실행되는 작업을 여기서 처리
<8>onPause()
-프래그먼트 일시정지시 호출
-상태저장, 스레드 중지
<9>onStop()
-프래그먼트가 사용자에게 보이지 않을때 호출
-리소스 해제, 스레드 정지
<10>onDestroyView()
-프래그먼트의 뷰와 관련 리소스 정리시 호출
<11>onDestroy()
-프래그먼트 파괴시 호출
-프래그먼트 상태 정리 및 리소스 해제
<12>onDetach()
-프래그먼트를 액티비티로부터 분리시 호출
-액티비티와의 모든 연결 해제
-onPause()에 들어가는 경우: 부모액티비티나 다른 프래그먼트로 대체되는 경우 onPause로 넘어가고 이후 onDestroyView()까지 진행되면서 기존의 뷰는 전부 해제됨
=>이후 다시 돌아오면 뷰에 변경사항은 전부 초기화되고 초기 화면이 띄워짐
@프래그먼트에서 뷰바인딩 하는 방법(메모리 누수를 막기위함)
-fragment의 뷰는 onDestroyView에서 사라지지만 fragment는 onDestroy가 호출되어야 사라진다.
-즉, binding을 생성하면 없애주지 않는 이상 사라지지않고 메모리 누수를 일으킨다.
-예시: 한 레이아웃에 프레그먼트를 바꾸면서 보여줄 경우 onDestroyView()까지만 가기때문에 한번 생성된 프레그먼트는 사라지지 않는다.
private var binding:FragmentFirstBinding? =null
private val binding get() = _binding!!
.
.
.
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentFirstBinding.inflate(inflater, container, false)
return binding.root
}
override fun onDestroyView(){
super.onDestroyView()
_binding = null
}
{1} binding과 _binding을 두 개 쓰는 이유:
-onDestroyView()에서 null로 값을 바꾸기 위해서는 타입을 nullable로 만들어줘야 하는데 이 경우 binding을 쓸때마다 널처리를 해줘야한다.
-그러나 _binding에 !!처리를 해줘서 get()으로 binding에 할당하면 쓸 때 마다 널처리를 해야하는 귀찮음을 없앨 수 있다.
{2}값을 대입 삭제하는것은 _binding에서 하고 사용하는것은 binding에서 함.
(4)프래그먼트 사용하는 이유
-Activity보단 fragment로 일부만 바꾸는 것이 자원 사용량이 적음
-재사용 가능한 레이아웃을 분리해 관리 가능
-한 Activity에서 여러 화면 보여줄 수 있음
(5)프래그먼트 사용법
<1>xml레이아웃 생성
<2>프래그먼트 클래스 정의
class SecondFragment : Fragment() {
private var _binding: FragmentSecondBinding?=null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding=FragmentSecondBinding.inflate(inflater,container,false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding=null
}
}
<3>gradle에서 dependencies에서 추가
implementation("androidx.fragment:fragment-ktx:1.8.1")
<4> 코드에서 동적으로 프래그먼트 추가
private fun setFragment(frag:Fragment){
supportFragmentManager.commit{
replace(binding.frameLayout.id,frag)
setReorderingAllowed(true)
addToBackStack("")
}
}
-replace(id,fragment): 해당 id의 레이아웃에 fragment를 바꿔 넣음
-setReorderingAllowed(true): 여러 transaction사용시 불필요한 프레그먼트를 실행시키지 않거나 나중에도 필요한 프래그먼트를 완전히 제거하지(onDetach())하지 않는것.
@예시
[1] A 프레그먼트를 추가하고 (add) B프레그먼트를 추가한다하자(add)
[2]원래라면 A가 onAttach() ~ onReumse()이 우선 뜨고
[3]이후 A는 onPause() ~ onDestroyView()가 뜨고 B가 추가되며 B는 onAttach() ~ onResume()콜백 함수가 실행된다.
=> setReorderingAllowed(true)를 쓰면 불필요하게 A가 생성되지 않고 B만 생성됨
-addToBackStack(String?): FragmentManager상의 백스택에 transaction(commit으로 묶인 단위)을 채워넣는다.
=>뒤로가기 누를 시 이전 프래그먼트가 나오게 된다.
=>최종적으로 모든 프레그먼트가 없는 상태까지 감.
=>String? 부분은 백스택에 들어갈때 transaction의 이름. 필요없으면 null을 넣어도 된다.
@popBackStack(): 뒤로가기를 누를 때 처럼 백스택에서 transaction을 하나씩 빼냄
supportFragmentManager.popBackStack()
=>String값을 넣어 특정 transaction위의 스택을 전부 비울 수 있다.
fragmentManager.popBackStack("hello2", FragmentManager.POP_BACK_STACK_INCLUSIVE)
@백스택에서 생명주기 상태: onPause()상태로 유지된다.
@childFragmentManager&parentFragmentManager
[1]사용: 프래그먼트 내에서 사용하는 것으로 외부 프래그먼트매니저를 참조하게 해준다.
[2]종류
- childFragmentManager:프래그먼트 내부의 자체적인 프래그먼트매니저
=>프래그먼트 내에 프래그먼트를 넣는 경우 이것을 사용한다.
- parentFragmentManager:상위 프래그먼트 혹은 액티비티의 프래그먼트 매니저
=>프래그먼트에서 상위에 존재하는 프래그먼트나 액티비티의 프래그먼트 매니저를 사용할 시 이것을 사용
@ setPrimaryNavigationFragment(true)
[1]프래그먼트 내부에 프래그먼트가 있는 경우 해당 프래그먼트부터 지워줌
=>즉, childFragmentManager의 백스택에 있는 프래그먼트부터 지워준다.
[2]설정을 안 한 경우: 프래그먼트가 지워지면서 안에 있는 child의 백스택은 한번에 통으로 날아감
<5>Transaction
[1]commit으로 묶이는 작업단위를 transaction이라 한다.
[2]작업 종류
-add(containerId, Fragment, tag:String) : 프래그먼트를 추가한다.
-remove(fragment): 프래그먼트를 제거 한다.
supportFragmentManager.getFragmentByTag(태그명:String)
=>기존에 추가되어 있는 프래그먼트를 태그를 이용해서 참조를 가져온다.
-detach&attach
{1}detach(Fragment): 프래그먼트를 떼어내는데 완전히 프래그먼트를 없애는게 아닌 onDestroyView()까지만 간다.
=>즉 보이지는 않지만 container에는 남아있는것
{2}attach(Fragment): detach한 프래그먼트를 onCreateView부터 다시 시작시켜 사용자에게 보이게 한다.
-show(Fragment)&hide(Fragment)
{1}그저 보이거나 안보이게만 해준다.
{2}어떠한 생명주기도 타지 않는다.
'코틀린-안드로이드' 카테고리의 다른 글
51일차)알고리즘 문제(억억단을 외우자, 무인도 여행) (0) | 2024.07.13 |
---|---|
50일차)알고리즘 문제(두 큐 합 같게 만들기), 숙련 1주차 강의(프래그먼트 데이터 전달, 다이얼로그, 알림) (0) | 2024.07.12 |
48일차)알고리즘 문제(삼각 달팽이, 블록 게임), 숙련 1주차 강의(뷰바인딩, 어댑터뷰) (0) | 2024.07.10 |
47일차)알고리즘 문제(큰 수 만들기), 챌린지반 3주차 강의(디자인 패턴, MVVM), 챌린지반 과제 (1) | 2024.07.09 |
46일차)알고리즘 문제(경사로의 개수, 택배 상자), 팀프로젝트 마무리 및 발표, 비행기 전광판 과제 (0) | 2024.07.08 |