[TIL] Day 14 알고리즘 문제 풀기 & SliverGrid & SliverList & FadeInImage

현서·2025년 12월 11일

[TIL] Flutter 9기

목록 보기
26/102
post-thumbnail

알고리즘 문제 풀기

☕️ Two Sum

문제 링크

* 문제
정수 배열 nums와 정수 target이 주어진다.
두 수를 더해 target이 되는 두 숫자의 인덱스를 반환하라., 같은 원소를 두 번 사용할 수는 없다.
정답은 어떤 순서로 반환해도 상관 없다.

* 예시 1
입력:
nums = [2,7,11,15], target = 9
출력:
[0,1]
설명: nums[0] + nums[1] = 9 이므로 [0, 1]을 반환.

* 예시 2
입력:
nums = [3,2,4], target = 6
출력:
[1,2]

* 예시 3
입력:
nums = [3,3], target = 6
출력:
[0,1]

* 제약 조건
2 <= nums.length <= 10-10<= nums[i] <= 10-10<= target <= 10⁹
가능한 정답은 오직 하나만 존재한다.

반복문으로 nums 리스트를 돌면서 더해주고 더한 값이 target 값이라면 해당 인덱스를 기록하는 식으로 생각을 했다.

class Solution {
  List<int> twoSum(List<int> nums, int target) {
    Set<int> idexList = {};
    for (var i = 1; i < nums.length; i++) {
      for (var j = 0; j < nums.length; j++) {
        if (nums[i] + nums[j] == target) {
          idexList.addAll([i, j]);
        }
      }
    }
    return idexList.toList();
  }
}

그래서 만든 게 요친구 그런데 nums = [-1,-2,-3,-4,-5] target = -8을 만나면 정답은 [2,4]지만 내 코드는 [2,4,3]을 반환하는 문제가 생겼다. i랑 j랑 안 겹치게 하려고 i를 1부터 시작하게 했는데 그게 문제였던 것 같다. 그래서 if문에 조건을 하나 더 추가했다.

class Solution {
  List<int> twoSum(List<int> nums, int target) {
    Set<int> idexList = {};
    for (var i = 0; i < nums.length; i++) {
      for (var j = 0; j < nums.length; j++) {
        if (i != j && nums[i] + nums[j] == target) {
          idexList.addAll([i, j]);
        }
      }
    }
    return idexList.toList();
  }
}

i랑 j랑 같지 않다는 조건도 넣어서 검사해서 제출했더니 헉.. 성공은 했지만 런타임이 192ms가 걸렸다;; 흐린 눈 하고 넘어갔다...

📍 튜터님과 Widget 공부

SliverList

SliverList란?

“스크롤 가능한 리스트”를 슬리버 형태로 제공하는 위젯.
ListView가 내부적으로 쓰는 구조의 기본 단위

스크롤 전체가 Sliver 방식으로 관리됨 → 성능 좋음
다른 Sliver들과 자연스럽게 섞임
SliverChildBuilderDelegate 또는 SliverChildListDelegate로 아이템 구성

SliverList(
  delegate: SliverChildBuilderDelegate(
    (context, index) {
      return Container(
        height: 80,
        color: Colors.grey[300],
        margin: const EdgeInsets.all(8),
        child: Text('Item $index'),
      );
    },
    childCount: 20,
  ),
)

SliverGrid

SliverGrid란?

그리드 레이아웃을 Sliver 방식으로 표현한 것
GridView의 Sliver 버전

특징

SliverList와 동일하게 스크롤을 Sliver 구조로 효율적으로 처리
여러 Sliver들과 자연스럽게 조합 가능

SliverGrid(
  delegate: SliverChildBuilderDelegate(
    (context, index) {
      return Container(
        color: Colors.blue,
      );
    },
    childCount: 30,
  ),
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: 3,
    childAspectRatio: 1,
  ),
)

ListView / GridView 와 SliverList / SliverGrid 차이

비교 항목ListView / GridViewSliverList / SliverGrid
구조단일 스크롤 위젯Sliver 구조 (여러 스크롤 조합 가능)
AppBar와 연동AppBar 아래 고정SliverAppBar와 자연스럽게 연동 (확장/축소 가능)
여러 섹션 결합어려움. SingleChildScrollView + Column 필요Sliver들끼리 바로 이어붙이면 됨
용도단일 리스트/그리드복합 스크롤 화면(ex. 앱 메인 페이지)

언제 Sliver 쓰면 좋은가?

SliverAppBar + 리스트/그리드 조합
Pinterest 스타일 화면
헤더 → 리스트 → 배너 → 그리드 → 푸터 이런 다양한 섹션 있는 스크린
스크롤에 따라 UI 변하는 화면

언제 ListView/GridView 쓰면 충분한가?

그냥 리스트, 그리드만 있다
SliverAppBar 안 씀
복잡한 스크린 구조가 아님
이런 경우엔 그냥 ListView 써도 됨

FadeInImage

FadeInImage란?

네트워크/비동기 이미지가 로드될 때 플레이스홀더 → 실제 이미지로 부드럽게 페이드인(교차 페이드) 시켜주는 위젯
내부적으로 ImageProvider(예: AssetImage, NetworkImage, MemoryImage)를 사용

주요 생성자

FadeInImage({ required ImageProvider placeholder, required ImageProvider image, ... }) — 직접 ImageProvider 전달

FadeInImage.assetNetwork({ required String placeholder, required String image, ... }) — 흔하게 쓰는 편리 생성자

FadeInImage.memoryNetwork({ required Uint8List placeholder, required String image, ... }) — 메모리 바이트 플레이스홀더 사용

자주 쓰는 파라미터

placeholder / image — 필수, ImageProvider
width, height, fit — 레이아웃 제어
fadeInDuration / fadeOutDuration — 애니메이션 시간 (Duration)
fadeInCurve / fadeOutCurve — 애니메이션 커브
placeholderScale — 플레이스홀더의 스케일링

예시

FadeInImage.assetNetwork(
  placeholder: 'assets/placeholder.png',
  image: 'https://picsum.photos/300/300',
  width: 120,
  height: 120,
  fit: BoxFit.cover,
  fadeInDuration: Duration(milliseconds: 300),
);

공부 소감

과제 제출을 완료해서 튜터님께 따로 과제를 받았다. 플러터로 클론 어플 구현해보는 과제였는데 아직 헷갈리는 위젯들이 몇 가지 있어서 주말에 정리해봐야겠당~

0개의 댓글